Download build archive (if exists) from cloud for given revision and perform bisect.
[chromium-blink-merge.git] / chrome / browser / memory_details_android.cc
blobfab8422f04985e4d0528f8a82ed4f77776241f62
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 "chrome/common/chrome_constants.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/common/process_type.h"
17 #include "grit/chromium_strings.h"
18 #include "ui/base/l10n/l10n_util.h"
20 using base::ProcessEntry;
21 using base::ProcessId;
22 using content::BrowserThread;
24 namespace {
26 // A helper for |CollectProcessData()| to include the chrome sandboxed
27 // processes in android which are not running as a child of the browser
28 // process.
29 void AddNonChildChromeProcesses(
30 std::vector<ProcessMemoryInformation>* processes) {
31 base::ProcessIterator process_iter(NULL);
32 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
33 const std::vector<std::string>& cmd_args = process_entry->cmd_line_args();
34 if (cmd_args.empty() ||
35 cmd_args[0].find(chrome::kHelperProcessExecutableName) ==
36 std::string::npos) {
37 continue;
39 ProcessMemoryInformation info;
40 info.pid = process_entry->pid();
41 processes->push_back(info);
45 // For each of the pids, collect memory information about that process
46 // and append a record to |out|.
47 void GetProcessDataMemoryInformation(
48 const std::set<ProcessId>& pids, ProcessData* out) {
49 for (std::set<ProcessId>::const_iterator i = pids.begin(); i != pids.end();
50 ++i) {
51 ProcessMemoryInformation pmi;
53 pmi.pid = *i;
54 pmi.num_processes = 1;
56 if (pmi.pid == base::GetCurrentProcId())
57 pmi.process_type = content::PROCESS_TYPE_BROWSER;
58 else
59 pmi.process_type = content::PROCESS_TYPE_UNKNOWN;
61 scoped_ptr<base::ProcessMetrics> metrics(
62 base::ProcessMetrics::CreateProcessMetrics(*i));
63 metrics->GetWorkingSetKBytes(&pmi.working_set);
65 out->processes.push_back(pmi);
69 // Find all children of the given process.
70 void GetAllChildren(const std::vector<ProcessEntry>& processes,
71 const std::set<ProcessId>& roots,
72 std::set<ProcessId>* out) {
73 *out = roots;
75 std::set<ProcessId> wavefront;
76 for (std::set<ProcessId>::const_iterator i = roots.begin(); i != roots.end();
77 ++i) {
78 wavefront.insert(*i);
81 while (wavefront.size()) {
82 std::set<ProcessId> next_wavefront;
83 for (std::vector<ProcessEntry>::const_iterator i = processes.begin();
84 i != processes.end(); ++i) {
85 if (wavefront.count(i->parent_pid())) {
86 out->insert(i->pid());
87 next_wavefront.insert(i->pid());
91 wavefront.clear();
92 wavefront.swap(next_wavefront);
96 } // namespace
98 MemoryDetails::MemoryDetails()
99 : user_metrics_mode_(UPDATE_USER_METRICS) {
102 ProcessData* MemoryDetails::ChromeBrowser() {
103 return &process_data_[0];
106 void MemoryDetails::CollectProcessData(
107 const std::vector<ProcessMemoryInformation>& chrome_processes) {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
110 std::vector<ProcessMemoryInformation> all_processes(chrome_processes);
111 AddNonChildChromeProcesses(&all_processes);
113 std::vector<ProcessEntry> processes;
114 base::ProcessIterator process_iter(NULL);
115 while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
116 processes.push_back(*process_entry);
119 std::set<ProcessId> roots;
120 roots.insert(base::GetCurrentProcId());
121 for (std::vector<ProcessMemoryInformation>::const_iterator
122 i = all_processes.begin(); i != all_processes.end(); ++i) {
123 roots.insert(i->pid);
126 std::set<ProcessId> current_browser_processes;
127 GetAllChildren(processes, roots, &current_browser_processes);
129 ProcessData current_browser;
130 GetProcessDataMemoryInformation(current_browser_processes, &current_browser);
131 current_browser.name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
132 current_browser.process_name =
133 reinterpret_cast<unsigned int>(chrome::kBrowserProcessExecutableName);
134 process_data_.push_back(current_browser);
136 // Finally return to the browser thread.
137 BrowserThread::PostTask(
138 BrowserThread::UI, FROM_HERE,
139 base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));