Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(657)

Unified Diff: chrome/browser/chromeos/arc/arc_process_service.cc

Issue 2441563002: arc: Create intermediate directories in c/b/c/arc (Closed)
Patch Set: Re-rebase to ToT Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
deleted file mode 100644
index 4763810caf3020198b961d2683157cd492ee34de..0000000000000000000000000000000000000000
--- a/chrome/browser/chromeos/arc/arc_process_service.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// The main point of this class is to cache ARC proc nspid<->pid mapping
-// globally. Since the calculation is costly, a dedicated worker thread is
-// used. All read/write of its internal data structure (i.e., the mapping)
-// should be on this thread.
-
-#include "chrome/browser/chromeos/arc/arc_process_service.h"
-
-#include <algorithm>
-#include <queue>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/process/process.h"
-#include "base/process/process_iterator.h"
-#include "base/task_runner_util.h"
-#include "base/trace_event/trace_event.h"
-#include "components/arc/arc_bridge_service.h"
-#include "content/public/browser/browser_thread.h"
-
-namespace arc {
-
-using base::kNullProcessId;
-using base::Process;
-using base::ProcessId;
-using base::SequencedWorkerPool;
-using std::vector;
-
-namespace {
-
-// Weak pointer. This class is owned by ArcServiceManager.
-ArcProcessService* g_arc_process_service = nullptr;
-static constexpr char kInitName[] = "/init";
-static constexpr bool kNotFocused = false;
-static constexpr int64_t kNoActivityTimeInfo = 0L;
-
-// Matches the process name "/init" in the process tree and get the
-// corresponding process ID.
-base::ProcessId GetArcInitProcessId(
- const base::ProcessIterator::ProcessEntries& entry_list) {
- for (const base::ProcessEntry& entry : entry_list) {
- if (entry.cmd_line_args().empty()) {
- continue;
- }
- // TODO(nya): Add more constraints to avoid mismatches.
- const std::string& process_name = entry.cmd_line_args()[0];
- if (process_name == kInitName) {
- return entry.pid();
- }
- }
- return base::kNullProcessId;
-}
-
-std::vector<ArcProcess> GetArcSystemProcessList() {
- std::vector<ArcProcess> ret_processes;
- const base::ProcessIterator::ProcessEntries& entry_list =
- base::ProcessIterator(nullptr).Snapshot();
- const base::ProcessId arc_init_pid = GetArcInitProcessId(entry_list);
-
- if (arc_init_pid == base::kNullProcessId) {
- return ret_processes;
- }
-
- // Enumerate the child processes of ARC init for gathering ARC System
- // Processes.
- for (const base::ProcessEntry& entry : entry_list) {
- if (entry.cmd_line_args().empty()) {
- continue;
- }
- // TODO(hctsai): For now, we only gather direct child process of init, need
- // to get the processes below. For example, installd might fork dex2oat and
- // it can be executed for minutes.
- if (entry.parent_pid() == arc_init_pid) {
- const base::ProcessId child_pid = entry.pid();
- const base::ProcessId child_nspid =
- base::Process(child_pid).GetPidInNamespace();
- if (child_nspid != base::kNullProcessId) {
- const std::string& process_name = entry.cmd_line_args()[0];
- // The is_focused and last_activity_time is not needed thus mocked
- ret_processes.emplace_back(child_nspid, child_pid, process_name,
- mojom::ProcessState::PERSISTENT, kNotFocused,
- kNoActivityTimeInfo);
- }
- }
- }
- return ret_processes;
-}
-
-void UpdateNspidToPidMap(
- scoped_refptr<ArcProcessService::NSPidToPidMap> pid_map) {
- TRACE_EVENT0("browser", "ArcProcessService::UpdateNspidToPidMap");
-
- // NB: Despite of its name, ProcessIterator::Snapshot() may return
- // inconsistent information because it simply walks procfs. Especially
- // we must not assume the parent-child relationships are consistent.
- const base::ProcessIterator::ProcessEntries& entry_list =
- base::ProcessIterator(nullptr).Snapshot();
-
- // Construct the process tree.
- // NB: This can contain a loop in case of race conditions.
- std::unordered_map<ProcessId, std::vector<ProcessId>> process_tree;
- for (const base::ProcessEntry& entry : entry_list)
- process_tree[entry.parent_pid()].push_back(entry.pid());
-
- ProcessId arc_init_pid = GetArcInitProcessId(entry_list);
-
- // Enumerate all processes under ARC init and create nspid -> pid map.
- if (arc_init_pid != kNullProcessId) {
- std::queue<ProcessId> queue;
- std::unordered_set<ProcessId> visited;
- queue.push(arc_init_pid);
- while (!queue.empty()) {
- ProcessId pid = queue.front();
- queue.pop();
- // Do not visit the same process twice. Otherwise we may enter an infinite
- // loop if |process_tree| contains a loop.
- if (!visited.insert(pid).second)
- continue;
-
- const ProcessId nspid = base::Process(pid).GetPidInNamespace();
-
- // All ARC processes should be in namespace so nspid is usually non-null,
- // but this can happen if the process has already gone.
- // Only add processes we're interested in (those appear as keys in
- // |pid_map|).
- if (nspid != kNullProcessId && pid_map->find(nspid) != pid_map->end())
- (*pid_map)[nspid] = pid;
-
- for (ProcessId child_pid : process_tree[pid])
- queue.push(child_pid);
- }
- }
-}
-
-std::vector<ArcProcess> FilterProcessList(
- const ArcProcessService::NSPidToPidMap& pid_map,
- mojo::Array<mojom::RunningAppProcessInfoPtr> processes) {
- std::vector<ArcProcess> ret_processes;
- for (const auto& entry : processes) {
- const auto it = pid_map.find(entry->pid);
- // The nspid could be missing due to race condition. For example, the
- // process is still running when we get the process snapshot and ends when
- // we update the nspid to pid mapping.
- if (it == pid_map.end() || it->second == base::kNullProcessId) {
- continue;
- }
- // Constructs the ArcProcess instance if the mapping is found.
- ArcProcess arc_process(entry->pid, pid_map.at(entry->pid),
- entry->process_name, entry->process_state,
- entry->is_focused, entry->last_activity_time);
- // |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;
-}
-
-std::vector<ArcProcess> UpdateAndReturnProcessList(
- scoped_refptr<ArcProcessService::NSPidToPidMap> nspid_map,
- mojo::Array<mojom::RunningAppProcessInfoPtr> processes) {
- ArcProcessService::NSPidToPidMap& pid_map = *nspid_map;
- // Cleanup dead pids in the cache |pid_map|.
- std::unordered_set<ProcessId> nspid_to_remove;
- for (const auto& entry : pid_map) {
- nspid_to_remove.insert(entry.first);
- }
- bool unmapped_nspid = false;
- 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) {
- pid_map[entry->pid] = base::kNullProcessId;
- unmapped_nspid = true;
- }
- }
- for (const auto& entry : nspid_to_remove) {
- pid_map.erase(entry);
- }
-
- // The operation is costly so avoid calling it when possible.
- if (unmapped_nspid) {
- UpdateNspidToPidMap(nspid_map);
- }
-
- return FilterProcessList(pid_map, std::move(processes));
-}
-
-void Reset(scoped_refptr<ArcProcessService::NSPidToPidMap> pid_map) {
- if (pid_map.get())
- pid_map->clear();
-}
-
-} // namespace
-
-ArcProcessService::ArcProcessService(ArcBridgeService* bridge_service)
- : ArcService(bridge_service),
- heavy_task_thread_("ArcProcessServiceThread"),
- nspid_to_pid_(new NSPidToPidMap()),
- weak_ptr_factory_(this) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- arc_bridge_service()->process()->AddObserver(this);
- DCHECK(!g_arc_process_service);
- g_arc_process_service = this;
- heavy_task_thread_.Start();
-}
-
-ArcProcessService::~ArcProcessService() {
- DCHECK(g_arc_process_service == this);
- heavy_task_thread_.Stop();
- g_arc_process_service = nullptr;
- arc_bridge_service()->process()->RemoveObserver(this);
-}
-
-// static
-ArcProcessService* ArcProcessService::Get() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- return g_arc_process_service;
-}
-
-void ArcProcessService::OnInstanceReady() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- GetTaskRunner()->PostTask(FROM_HERE, base::Bind(&Reset, nspid_to_pid_));
-}
-
-void ArcProcessService::RequestSystemProcessList(
- RequestProcessListCallback callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- base::PostTaskAndReplyWithResult(GetTaskRunner().get(), FROM_HERE,
- base::Bind(&GetArcSystemProcessList),
- callback);
-}
-
-bool ArcProcessService::RequestAppProcessList(
- RequestProcessListCallback callback) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- mojom::ProcessInstance* process_instance =
- arc_bridge_service()->process()->GetInstanceForMethod(
- "RequestProcessList");
- if (!process_instance) {
- return false;
- }
- process_instance->RequestProcessList(
- base::Bind(&ArcProcessService::OnReceiveProcessList,
- weak_ptr_factory_.GetWeakPtr(), callback));
- return true;
-}
-
-void ArcProcessService::OnReceiveProcessList(
- const RequestProcessListCallback& callback,
- mojo::Array<mojom::RunningAppProcessInfoPtr> instance_processes) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
- base::PostTaskAndReplyWithResult(
- GetTaskRunner().get(), FROM_HERE,
- base::Bind(&UpdateAndReturnProcessList, nspid_to_pid_,
- base::Passed(&instance_processes)),
- callback);
-}
-
-scoped_refptr<base::SingleThreadTaskRunner> ArcProcessService::GetTaskRunner() {
- return heavy_task_thread_.task_runner();
-}
-
-inline ArcProcessService::NSPidToPidMap::NSPidToPidMap() {}
-
-inline ArcProcessService::NSPidToPidMap::~NSPidToPidMap() {}
-
-} // namespace arc
« no previous file with comments | « chrome/browser/chromeos/arc/arc_process_service.h ('k') | chrome/browser/chromeos/arc/arc_service_launcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698