Chromium Code Reviews| 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 |