OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // The main point of this class is to cache ARC proc nspid<->pid mapping | 5 // The main point of this class is to cache ARC proc nspid<->pid mapping |
6 // globally. Since the calculation is costly, a dedicated worker thread is | 6 // globally. Since the calculation is costly, a dedicated worker thread is |
7 // used. All read/write of its internal data structure (i.e., the mapping) | 7 // used. All read/write of its internal data structure (i.e., the mapping) |
8 // should be on this thread. | 8 // should be on this thread. |
9 | 9 |
10 #include "chrome/browser/chromeos/arc/arc_process_service.h" | 10 #include "chrome/browser/chromeos/arc/arc_process_service.h" |
11 | 11 |
12 #include <queue> | 12 #include <queue> |
13 #include <set> | 13 #include <set> |
14 #include <string> | 14 #include <string> |
15 | 15 |
16 #include "base/process/process.h" | 16 #include "base/process/process.h" |
17 #include "base/process/process_iterator.h" | 17 #include "base/process/process_iterator.h" |
18 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
19 #include "base/trace_event/trace_event.h" | 19 #include "base/trace_event/trace_event.h" |
20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
21 | 21 |
22 namespace arc { | 22 namespace arc { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 const char kSequenceToken[] = "arc_process_service"; | 26 const char kSequenceToken[] = "arc_process_service"; |
Yusuke Sato
2016/06/02 21:50:11
s/const/constexpr/
Hsu-Cheng
2016/06/29 10:33:57
Done.
| |
27 | 27 |
28 // Weak pointer. This class is owned by ArcServiceManager. | 28 // Weak pointer. This class is owned by ArcServiceManager. |
29 ArcProcessService* g_arc_process_service = nullptr; | 29 ArcProcessService* g_arc_process_service = nullptr; |
30 | 30 |
31 } // namespace | 31 } // namespace |
32 | 32 |
33 using base::kNullProcessId; | 33 using base::kNullProcessId; |
34 using base::Process; | 34 using base::Process; |
35 using base::ProcessId; | 35 using base::ProcessId; |
36 using base::SequencedWorkerPool; | 36 using base::SequencedWorkerPool; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 FROM_HERE, | 70 FROM_HERE, |
71 base::Bind(&ArcProcessService::Reset, | 71 base::Bind(&ArcProcessService::Reset, |
72 weak_ptr_factory_.GetWeakPtr())); | 72 weak_ptr_factory_.GetWeakPtr())); |
73 } | 73 } |
74 | 74 |
75 void ArcProcessService::Reset() { | 75 void ArcProcessService::Reset() { |
76 DCHECK(thread_checker_.CalledOnValidThread()); | 76 DCHECK(thread_checker_.CalledOnValidThread()); |
77 nspid_to_pid_.clear(); | 77 nspid_to_pid_.clear(); |
78 } | 78 } |
79 | 79 |
80 bool ArcProcessService::RequestProcessList( | 80 bool ArcProcessService::RequestSystemProcessList( |
cylee1
2016/06/02 20:58:45
nit: can you try to consolidate the logic here and
Hsu-Cheng
2016/06/29 10:33:57
Done.
| |
81 RequestProcessListCallback callback) { | 81 RequestProcessListCallback callback) { |
82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 82 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
83 | 83 |
84 auto ret_processes = new vector<ArcProcess>(); | |
85 auto runner = worker_pool_->GetSequencedTaskRunner( | |
Yusuke Sato
2016/06/02 21:50:11
Why does this have to be sequenced, btw?
Hsu-Cheng
2016/06/29 10:33:57
The pool size here is 1 and this is for avoid runn
| |
86 worker_pool_->GetNamedSequenceToken(kSequenceToken)); | |
87 runner->PostTaskAndReply( | |
88 FROM_HERE, base::Bind(&ArcProcessService::FetchAndReturnSystemProcessList, | |
89 weak_ptr_factory_.GetWeakPtr(), | |
90 base::Unretained(ret_processes)), | |
91 base::Bind(&ArcProcessService::CallbackRelay, | |
92 weak_ptr_factory_.GetWeakPtr(), callback, | |
93 base::Owned(ret_processes))); | |
94 return true; | |
cylee1
2016/06/02 20:58:45
Always return true?
Hsu-Cheng
2016/06/29 10:33:57
Done.
| |
95 } | |
96 | |
97 void ArcProcessService::FetchAndReturnSystemProcessList( | |
cylee1
2016/06/02 20:58:44
Maybe GetArcSystemProcessList
Hsu-Cheng
2016/06/29 10:33:57
Done.
| |
98 vector<ArcProcess>* ret_processes) { | |
99 DCHECK(thread_checker_.CalledOnValidThread()); | |
100 | |
101 const base::ProcessIterator::ProcessEntries& entry_list = | |
102 base::ProcessIterator(nullptr).Snapshot(); | |
103 ProcessId arc_init_pid = GetArcInitProcessId(entry_list); | |
cylee1
2016/06/02 20:58:45
You should check if it's kNullProcessId before doi
Hsu-Cheng
2016/06/29 10:33:56
Done.
| |
104 | |
105 // Enumerate the child processes of ARC init for gaterhing ARC system procces | |
cylee1
2016/06/02 20:58:44
nit: gathering
nit: processes
I think you should
Hsu-Cheng
2016/06/29 10:33:57
Added system process definition in arc_process_ser
| |
106 for (const base::ProcessEntry& entry : entry_list) { | |
107 std::string process_name = | |
cylee1
2016/06/02 20:58:44
why not get process_name inside the if at line 109
Hsu-Cheng
2016/06/29 10:33:57
Done.
| |
108 !entry.cmd_line_args().empty() ? entry.cmd_line_args()[0] : ""; | |
109 if (entry.parent_pid() == arc_init_pid) { | |
Yusuke Sato
2016/06/02 21:50:11
This will only detect direct children of the init
Hsu-Cheng
2016/06/29 10:33:57
You are right. I miss the case. I will make a new
| |
110 ProcessId child_pid = entry.pid(); | |
111 ProcessId child_nspid = base::Process(child_pid).GetPidInNamespace(); | |
112 if (child_nspid != kNullProcessId) { | |
113 ArcProcess arc_process = {child_nspid, child_pid, process_name, | |
Yusuke Sato
2016/06/02 21:50:11
This no longer compiles once you rebase your Chrom
Hsu-Cheng
2016/06/29 10:33:57
Done.
| |
114 mojom::ProcessState::PERSISTENT}; | |
115 ret_processes->push_back(arc_process); | |
116 } | |
117 } | |
118 } | |
119 } | |
120 | |
121 bool ArcProcessService::RequestAppProcessList( | |
122 RequestProcessListCallback callback) { | |
123 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
124 | |
84 arc::mojom::ProcessInstance* process_instance = | 125 arc::mojom::ProcessInstance* process_instance = |
85 arc_bridge_service()->process_instance(); | 126 arc_bridge_service()->process_instance(); |
86 if (!process_instance) { | 127 if (!process_instance) { |
87 return false; | 128 return false; |
88 } | 129 } |
89 process_instance->RequestProcessList( | 130 process_instance->RequestProcessList( |
90 base::Bind(&ArcProcessService::OnReceiveProcessList, | 131 base::Bind(&ArcProcessService::OnReceiveProcessList, |
91 weak_ptr_factory_.GetWeakPtr(), | 132 weak_ptr_factory_.GetWeakPtr(), |
92 callback)); | 133 callback)); |
93 return true; | 134 return true; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
194 // processes may have the same nspid. We need to get the proper subset of | 235 // processes may have the same nspid. We need to get the proper subset of |
195 // processes to create correct nspid -> pid map. | 236 // processes to create correct nspid -> pid map. |
196 | 237 |
197 // Construct the process tree. | 238 // Construct the process tree. |
198 // NB: This can contain a loop in case of race conditions. | 239 // NB: This can contain a loop in case of race conditions. |
199 map<ProcessId, vector<ProcessId> > process_tree; | 240 map<ProcessId, vector<ProcessId> > process_tree; |
200 for (const base::ProcessEntry& entry : entry_list) | 241 for (const base::ProcessEntry& entry : entry_list) |
201 process_tree[entry.parent_pid()].push_back(entry.pid()); | 242 process_tree[entry.parent_pid()].push_back(entry.pid()); |
202 | 243 |
203 // Find the ARC init process. | 244 // Find the ARC init process. |
204 ProcessId arc_init_pid = kNullProcessId; | 245 ProcessId arc_init_pid = GetArcInitProcessId(entry_list); |
205 for (const base::ProcessEntry& entry : entry_list) { | |
206 // TODO(nya): Add more constraints to avoid mismatches. | |
207 std::string process_name = | |
208 !entry.cmd_line_args().empty() ? entry.cmd_line_args()[0] : ""; | |
209 if (process_name == "/init") { | |
210 arc_init_pid = entry.pid(); | |
211 break; | |
212 } | |
213 } | |
214 | 246 |
215 // Enumerate all processes under ARC init and create nspid -> pid map. | 247 // Enumerate all processes under ARC init and create nspid -> pid map. |
216 if (arc_init_pid != kNullProcessId) { | 248 if (arc_init_pid != kNullProcessId) { |
217 std::queue<ProcessId> queue; | 249 std::queue<ProcessId> queue; |
218 std::set<ProcessId> visited; | 250 std::set<ProcessId> visited; |
219 queue.push(arc_init_pid); | 251 queue.push(arc_init_pid); |
220 while (!queue.empty()) { | 252 while (!queue.empty()) { |
221 ProcessId pid = queue.front(); | 253 ProcessId pid = queue.front(); |
222 queue.pop(); | 254 queue.pop(); |
223 // Do not visit the same process twice. Otherwise we may enter an infinite | 255 // Do not visit the same process twice. Otherwise we may enter an infinite |
(...skipping 10 matching lines...) Expand all Loading... | |
234 if (nspid != kNullProcessId && | 266 if (nspid != kNullProcessId && |
235 nspid_to_pid_.find(nspid) != nspid_to_pid_.end()) | 267 nspid_to_pid_.find(nspid) != nspid_to_pid_.end()) |
236 nspid_to_pid_[nspid] = pid; | 268 nspid_to_pid_[nspid] = pid; |
237 | 269 |
238 for (ProcessId child_pid : process_tree[pid]) | 270 for (ProcessId child_pid : process_tree[pid]) |
239 queue.push(child_pid); | 271 queue.push(child_pid); |
240 } | 272 } |
241 } | 273 } |
242 } | 274 } |
243 | 275 |
276 ProcessId ArcProcessService::GetArcInitProcessId( | |
277 const base::ProcessIterator::ProcessEntries& entry_list) { | |
278 // Find the ARC init process. | |
279 for (const base::ProcessEntry& entry : entry_list) { | |
280 // TODO(nya): Add more constraints to avoid mismatches. | |
281 std::string process_name = | |
282 !entry.cmd_line_args().empty() ? entry.cmd_line_args()[0] : ""; | |
283 if (process_name == "/init") { | |
284 return entry.pid(); | |
285 } | |
286 } | |
287 return kNullProcessId; | |
288 } | |
289 | |
244 } // namespace arc | 290 } // namespace arc |
OLD | NEW |