QUIC - cleanup changes to sync chromium tree with internal source.
[chromium-blink-merge.git] / chrome / browser / memory_details_android.cc
blob62ec6d7c773a3ecb86eeb473c12ac396ac318545
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 "chrome/grit/chromium_strings.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/common/process_type.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() {
102 ProcessData* MemoryDetails::ChromeBrowser() {
103 return &process_data_[0];
106 void MemoryDetails::CollectProcessData(
107 CollectionMode mode,
108 const std::vector<ProcessMemoryInformation>& chrome_processes) {
109 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
111 std::vector<ProcessMemoryInformation> all_processes(chrome_processes);
112 AddNonChildChromeProcesses(&all_processes);
114 std::vector<ProcessEntry> processes;
115 base::ProcessIterator process_iter(NULL);
116 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
117 processes.push_back(*process_entry);
120 std::set<ProcessId> roots;
121 roots.insert(base::GetCurrentProcId());
122 for (std::vector<ProcessMemoryInformation>::const_iterator
123 i = all_processes.begin(); i != all_processes.end(); ++i) {
124 roots.insert(i->pid);
127 std::set<ProcessId> current_browser_processes;
128 GetAllChildren(processes, roots, &current_browser_processes);
130 ProcessData current_browser;
131 GetProcessDataMemoryInformation(current_browser_processes, &current_browser);
132 current_browser.name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
133 current_browser.process_name =
134 base::ASCIIToUTF16(chrome::kBrowserProcessExecutableName);
135 process_data_.push_back(current_browser);
137 // Finally return to the browser thread.
138 BrowserThread::PostTask(
139 BrowserThread::UI, FROM_HERE,
140 base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));