This source file includes following definitions.
- AddNonChildChromeProcesses
- GetProcessDataMemoryInformation
- GetAllChildren
- ChromeBrowser
- CollectProcessData
#include "chrome/browser/memory_details.h"
#include <set>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process_iterator.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/process_type.h"
#include "grit/chromium_strings.h"
#include "ui/base/l10n/l10n_util.h"
using base::ProcessEntry;
using base::ProcessId;
using content::BrowserThread;
namespace {
void AddNonChildChromeProcesses(
std::vector<ProcessMemoryInformation>* processes) {
base::ProcessIterator process_iter(NULL);
while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
const std::vector<std::string>& cmd_args = process_entry->cmd_line_args();
if (cmd_args.empty() ||
cmd_args[0].find(chrome::kHelperProcessExecutableName) ==
std::string::npos) {
continue;
}
ProcessMemoryInformation info;
info.pid = process_entry->pid();
processes->push_back(info);
}
}
void GetProcessDataMemoryInformation(
const std::set<ProcessId>& pids, ProcessData* out) {
for (std::set<ProcessId>::const_iterator i = pids.begin(); i != pids.end();
++i) {
ProcessMemoryInformation pmi;
pmi.pid = *i;
pmi.num_processes = 1;
if (pmi.pid == base::GetCurrentProcId())
pmi.process_type = content::PROCESS_TYPE_BROWSER;
else
pmi.process_type = content::PROCESS_TYPE_UNKNOWN;
scoped_ptr<base::ProcessMetrics> metrics(
base::ProcessMetrics::CreateProcessMetrics(*i));
metrics->GetWorkingSetKBytes(&pmi.working_set);
out->processes.push_back(pmi);
}
}
void GetAllChildren(const std::vector<ProcessEntry>& processes,
const std::set<ProcessId>& roots,
std::set<ProcessId>* out) {
*out = roots;
std::set<ProcessId> wavefront;
for (std::set<ProcessId>::const_iterator i = roots.begin(); i != roots.end();
++i) {
wavefront.insert(*i);
}
while (wavefront.size()) {
std::set<ProcessId> next_wavefront;
for (std::vector<ProcessEntry>::const_iterator i = processes.begin();
i != processes.end(); ++i) {
if (wavefront.count(i->parent_pid())) {
out->insert(i->pid());
next_wavefront.insert(i->pid());
}
}
wavefront.clear();
wavefront.swap(next_wavefront);
}
}
}
MemoryDetails::MemoryDetails()
: user_metrics_mode_(UPDATE_USER_METRICS) {
}
ProcessData* MemoryDetails::ChromeBrowser() {
return &process_data_[0];
}
void MemoryDetails::CollectProcessData(
const std::vector<ProcessMemoryInformation>& chrome_processes) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
std::vector<ProcessMemoryInformation> all_processes(chrome_processes);
AddNonChildChromeProcesses(&all_processes);
std::vector<ProcessEntry> processes;
base::ProcessIterator process_iter(NULL);
while (const ProcessEntry* process_entry = process_iter.NextProcessEntry()) {
processes.push_back(*process_entry);
}
std::set<ProcessId> roots;
roots.insert(base::GetCurrentProcId());
for (std::vector<ProcessMemoryInformation>::const_iterator
i = all_processes.begin(); i != all_processes.end(); ++i) {
roots.insert(i->pid);
}
std::set<ProcessId> current_browser_processes;
GetAllChildren(processes, roots, ¤t_browser_processes);
ProcessData current_browser;
GetProcessDataMemoryInformation(current_browser_processes, ¤t_browser);
current_browser.name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
current_browser.process_name =
base::ASCIIToUTF16(chrome::kBrowserProcessExecutableName);
process_data_.push_back(current_browser);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));
}