Index: chrome/browser/chromeos/arc/arc_process_service.cc |
diff --git a/chrome/browser/chromeos/arc/arc_process_service.cc b/chrome/browser/chromeos/arc/arc_process_service.cc |
index 550ea0ae0c2f5a62cf0815969f2168c52a3a353c..8e8c810cb10a8f132ddb7e0952cb087f6496fe98 100644 |
--- a/chrome/browser/chromeos/arc/arc_process_service.cc |
+++ b/chrome/browser/chromeos/arc/arc_process_service.cc |
@@ -13,6 +13,7 @@ |
#include <set> |
#include <string> |
+#include "base/callback_forward.h" |
#include "base/process/process.h" |
#include "base/process/process_iterator.h" |
#include "base/task_runner_util.h" |
@@ -23,7 +24,7 @@ namespace arc { |
namespace { |
-const char kSequenceToken[] = "arc_process_service"; |
+constexpr char kSequenceToken[] = "arc_process_service"; |
// Weak pointer. This class is owned by ArcServiceManager. |
ArcProcessService* g_arc_process_service = nullptr; |
@@ -77,7 +78,51 @@ void ArcProcessService::Reset() { |
nspid_to_pid_.clear(); |
} |
-bool ArcProcessService::RequestProcessList( |
+void ArcProcessService::RequestSystemProcessList( |
+ RequestProcessListCallback callback) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ |
+ auto runner = worker_pool_->GetSequencedTaskRunner( |
+ worker_pool_->GetNamedSequenceToken(kSequenceToken)); |
+ base::PostTaskAndReplyWithResult( |
+ runner.get(), FROM_HERE, |
+ base::Bind(&ArcProcessService::GetArcSystemProcessList), callback); |
+} |
+ |
+// static |
+vector<ArcProcess> ArcProcessService::GetArcSystemProcessList() { |
+ vector<ArcProcess> ret_processes; |
+ const base::ProcessIterator::ProcessEntries& entry_list = |
+ base::ProcessIterator(nullptr).Snapshot(); |
+ ProcessId arc_init_pid = GetArcInitProcessId(entry_list); |
+ |
+ if (arc_init_pid == kNullProcessId) { |
+ return ret_processes; |
+ } |
+ |
+ // Enumerate the child processes of ARC init for gathering ARC System |
+ // Processes. |
+ for (const base::ProcessEntry& entry : entry_list) { |
+ // TODO(hctsai): For now, we only gather direct child process of init, need |
+ // to get the processes below. For example, intalled might |
Luis Héctor Chávez
2016/07/06 20:28:12
nit: installd
|
+ // fork dex2oat and it can be executed for minutes. |
+ if (entry.parent_pid() == arc_init_pid) { |
+ const ProcessId child_pid = entry.pid(); |
+ const ProcessId child_nspid = |
+ base::Process(child_pid).GetPidInNamespace(); |
+ const std::string process_name = |
+ !entry.cmd_line_args().empty() ? entry.cmd_line_args()[0] : ""; |
+ if (child_nspid != kNullProcessId) { |
+ ret_processes.emplace_back(child_nspid, child_pid, process_name, |
+ mojom::ProcessState::PERSISTENT); |
+ } |
+ } |
+ } |
+ |
+ return ret_processes; |
+} |
+ |
+bool ArcProcessService::RequestAppProcessList( |
RequestProcessListCallback callback) { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
@@ -93,60 +138,52 @@ bool ArcProcessService::RequestProcessList( |
return true; |
} |
+vector<ArcProcess> ArcProcessService::ConvertMojoProcess( |
+ mojo::Array<arc::mojom::RunningAppProcessInfoPtr>& mojo_processes) { |
+ vector<ArcProcess> ret_processes; |
+ |
+ for (const auto& entry : mojo_processes) { |
+ ArcProcess arc_process(entry->pid, nspid_to_pid_[entry->pid], |
+ entry->process_name, entry->process_state); |
+ // |entry->packages| is provided only when process.mojom's verion is >=4. |
+ if (entry->packages) { |
+ for (const auto& package : entry->packages) { |
+ arc_process.packages().push_back(package.get()); |
+ } |
+ } |
+ ret_processes.push_back(std::move(arc_process)); |
+ } |
+ |
+ return ret_processes; |
+} |
+ |
void ArcProcessService::OnReceiveProcessList( |
const RequestProcessListCallback& callback, |
mojo::Array<arc::mojom::RunningAppProcessInfoPtr> mojo_processes) { |
Luis Héctor Chávez
2016/07/06 20:28:12
nit: if possible, rename all the |mojo_processes|
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- auto raw_processes = new vector<mojom::RunningAppProcessInfoPtr>(); |
- mojo_processes.Swap(raw_processes); |
- |
- auto ret_processes = new vector<ArcProcess>(); |
- // Post to its dedicated worker thread to avoid race condition. |
- // Since no two tasks with the same token should be run at the same. |
- // Note: GetSequencedTaskRunner's shutdown behavior defaults to |
- // SKIP_ON_SHUTDOWN (ongoing task blocks shutdown). |
- // So in theory using Unretained(this) should be fine since the life cycle |
- // of |this| is the same as the main browser. |
- // To be safe I still use weak pointers, but weak_ptrs can only bind to |
- // methods without return values. That's why I can't use |
- // PostTaskAndReplyWithResult but handle the return object by myself. |
+ vector<ArcProcess> processes = ConvertMojoProcess(mojo_processes); |
auto runner = worker_pool_->GetSequencedTaskRunner( |
worker_pool_->GetNamedSequenceToken(kSequenceToken)); |
- runner->PostTaskAndReply( |
- FROM_HERE, |
- base::Bind(&ArcProcessService::UpdateAndReturnProcessList, |
- weak_ptr_factory_.GetWeakPtr(), |
- base::Owned(raw_processes), |
- base::Unretained(ret_processes)), |
- base::Bind(&ArcProcessService::CallbackRelay, |
- weak_ptr_factory_.GetWeakPtr(), |
- callback, |
- base::Owned(ret_processes))); |
+ base::PostTaskAndReplyWithResult( |
+ runner.get(), FROM_HERE, |
+ base::Bind(&ArcProcessService::UpdateAndReturnProcessList, this, |
+ base::Passed(&processes)), |
+ callback); |
} |
-void ArcProcessService::CallbackRelay( |
- const RequestProcessListCallback& callback, |
- const vector<ArcProcess>* ret_processes) { |
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
- callback.Run(*ret_processes); |
-} |
- |
-void ArcProcessService::UpdateAndReturnProcessList( |
- const vector<arc::mojom::RunningAppProcessInfoPtr>* raw_processes, |
- vector<ArcProcess>* ret_processes) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
+vector<ArcProcess> ArcProcessService::UpdateAndReturnProcessList( |
+ const vector<ArcProcess>& processes) { |
// Cleanup dead pids in the cache |nspid_to_pid_|. |
set<ProcessId> nspid_to_remove; |
for (const auto& entry : nspid_to_pid_) { |
nspid_to_remove.insert(entry.first); |
} |
bool unmapped_nspid = false; |
- for (const auto& entry : *raw_processes) { |
+ for (const auto& entry : processes) { |
// erase() returns 0 if coudln't find the key. It means a new process. |
- if (nspid_to_remove.erase(entry->pid) == 0) { |
- nspid_to_pid_[entry->pid] = kNullProcessId; |
+ if (nspid_to_remove.erase(entry.pid()) == 0) { |
+ nspid_to_pid_[entry.pid()] = kNullProcessId; |
unmapped_nspid = true; |
} |
} |
@@ -159,29 +196,24 @@ void ArcProcessService::UpdateAndReturnProcessList( |
UpdateNspidToPidMap(); |
} |
- PopulateProcessList(raw_processes, ret_processes); |
+ return PopulateProcessList(processes); |
} |
-void ArcProcessService::PopulateProcessList( |
- const vector<arc::mojom::RunningAppProcessInfoPtr>* raw_processes, |
- vector<ArcProcess>* ret_processes) { |
+vector<ArcProcess> ArcProcessService::PopulateProcessList( |
+ const vector<ArcProcess>& processes) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
+ vector<ArcProcess> ret_processes; |
- for (const auto& entry : *raw_processes) { |
- const auto it = nspid_to_pid_.find(entry->pid); |
+ for (const auto& entry : processes) { |
+ const auto it = nspid_to_pid_.find(entry.pid()); |
// In case the process already dies so couldn't find corresponding pid. |
if (it != nspid_to_pid_.end() && it->second != kNullProcessId) { |
- ArcProcess arc_process(entry->pid, it->second, entry->process_name, |
- entry->process_state); |
- // |entry->packages| is provided only when process.mojom's verion is >=4. |
- if (entry->packages) { |
- for (const auto& package : entry->packages) { |
- arc_process.packages().push_back(package.get()); |
- } |
- } |
- ret_processes->push_back(std::move(arc_process)); |
+ ArcProcess arc_process(entry.nspid(), entry.pid(), entry.process_name(), |
+ entry.process_state()); |
+ ret_processes.push_back(std::move(arc_process)); |
} |
} |
+ return ret_processes; |
} |
// Computes a map from PID in ARC namespace to PID in system namespace. |
@@ -208,16 +240,7 @@ void ArcProcessService::UpdateNspidToPidMap() { |
process_tree[entry.parent_pid()].push_back(entry.pid()); |
// Find the ARC init process. |
- ProcessId arc_init_pid = kNullProcessId; |
- for (const base::ProcessEntry& entry : entry_list) { |
- // TODO(nya): Add more constraints to avoid mismatches. |
- std::string process_name = |
- !entry.cmd_line_args().empty() ? entry.cmd_line_args()[0] : ""; |
- if (process_name == "/init") { |
- arc_init_pid = entry.pid(); |
- break; |
- } |
- } |
+ ProcessId arc_init_pid = GetArcInitProcessId(entry_list); |
// Enumerate all processes under ARC init and create nspid -> pid map. |
if (arc_init_pid != kNullProcessId) { |
@@ -248,4 +271,19 @@ void ArcProcessService::UpdateNspidToPidMap() { |
} |
} |
+// static |
+ProcessId ArcProcessService::GetArcInitProcessId( |
+ const base::ProcessIterator::ProcessEntries& entry_list) { |
+ // Find the ARC init process. |
+ for (const base::ProcessEntry& entry : entry_list) { |
+ // TODO(nya): Add more constraints to avoid mismatches. |
+ std::string process_name = |
+ !entry.cmd_line_args().empty() ? entry.cmd_line_args()[0] : ""; |
+ if (process_name == "/init") { |
+ return entry.pid(); |
+ } |
+ } |
+ return kNullProcessId; |
+} |
+ |
} // namespace arc |