Adding a router class to handle messages that expect responses.
[chromium-blink-merge.git] / chrome / browser / memory_details_android.cc
blob662ea9eed31c9e6550e85fb578a915b638764a99
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/memory_details.h"
7 #include <set>
8 #include <string>
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/process/process_iterator.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/common/process_type.h"
18 #include "grit/chromium_strings.h"
19 #include "ui/base/l10n/l10n_util.h"
21 using base::ProcessEntry;
22 using base::ProcessId;
23 using content::BrowserThread;
25 namespace {
27 // A helper for |CollectProcessData()| to include the chrome sandboxed
28 // processes in android which are not running as a child of the browser
29 // process.
30 void AddNonChildChromeProcesses(
31 std::vector<ProcessMemoryInformation>* processes) {
32 base::ProcessIterator process_iter(NULL);
33 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
34 const std::vector<std::string>& cmd_args = process_entry->cmd_line_args();
35 if (cmd_args.empty() ||
36 cmd_args[0].find(chrome::kHelperProcessExecutableName) ==
37 std::string::npos) {
38 continue;
40 ProcessMemoryInformation info;
41 info.pid = process_entry->pid();
42 processes->push_back(info);
46 // For each of the pids, collect memory information about that process
47 // and append a record to |out|.
48 void GetProcessDataMemoryInformation(
49 const std::set<ProcessId>& pids, ProcessData* out) {
50 for (std::set<ProcessId>::const_iterator i = pids.begin(); i != pids.end();
51 ++i) {
52 ProcessMemoryInformation pmi;
54 pmi.pid = *i;
55 pmi.num_processes = 1;
57 if (pmi.pid == base::GetCurrentProcId())
58 pmi.process_type = content::PROCESS_TYPE_BROWSER;
59 else
60 pmi.process_type = content::PROCESS_TYPE_UNKNOWN;
62 scoped_ptr<base::ProcessMetrics> metrics(
63 base::ProcessMetrics::CreateProcessMetrics(*i));
64 metrics->GetWorkingSetKBytes(&pmi.working_set);
66 out->processes.push_back(pmi);
70 // Find all children of the given process.
71 void GetAllChildren(const std::vector<ProcessEntry>& processes,
72 const std::set<ProcessId>& roots,
73 std::set<ProcessId>* out) {
74 *out = roots;
76 std::set<ProcessId> wavefront;
77 for (std::set<ProcessId>::const_iterator i = roots.begin(); i != roots.end();
78 ++i) {
79 wavefront.insert(*i);
82 while (wavefront.size()) {
83 std::set<ProcessId> next_wavefront;
84 for (std::vector<ProcessEntry>::const_iterator i = processes.begin();
85 i != processes.end(); ++i) {
86 if (wavefront.count(i->parent_pid())) {
87 out->insert(i->pid());
88 next_wavefront.insert(i->pid());
92 wavefront.clear();
93 wavefront.swap(next_wavefront);
97 } // namespace
99 MemoryDetails::MemoryDetails()
100 : user_metrics_mode_(UPDATE_USER_METRICS),
101 memory_growth_tracker_(NULL) {
104 ProcessData* MemoryDetails::ChromeBrowser() {
105 return &process_data_[0];
108 void MemoryDetails::CollectProcessData(
109 const std::vector<ProcessMemoryInformation>& chrome_processes) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
112 std::vector<ProcessMemoryInformation> all_processes(chrome_processes);
113 AddNonChildChromeProcesses(&all_processes);
115 std::vector<ProcessEntry> processes;
116 base::ProcessIterator process_iter(NULL);
117 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
118 processes.push_back(*process_entry);
121 std::set<ProcessId> roots;
122 roots.insert(base::GetCurrentProcId());
123 for (std::vector<ProcessMemoryInformation>::const_iterator
124 i = all_processes.begin(); i != all_processes.end(); ++i) {
125 roots.insert(i->pid);
128 std::set<ProcessId> current_browser_processes;
129 GetAllChildren(processes, roots, &current_browser_processes);
131 ProcessData current_browser;
132 GetProcessDataMemoryInformation(current_browser_processes, &current_browser);
133 current_browser.name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
134 current_browser.process_name =
135 base::ASCIIToUTF16(chrome::kBrowserProcessExecutableName);
136 process_data_.push_back(current_browser);
138 // Finally return to the browser thread.
139 BrowserThread::PostTask(
140 BrowserThread::UI, FROM_HERE,
141 base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));