1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/memory_details.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_version_info.h"
133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/mac/mac_util.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/process_util.h"
163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/process_info_snapshot.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_child_process_host.h"
23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/backing_store_manager.h"
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(viettrungluu): Many of the TODOs below are subsumed by a general need to
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// refactor the about:memory code (not just on Mac, but probably on other
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// platforms as well). I've filed crbug.com/25456.
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass RenderViewHostDelegate;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Known browsers which we collect details for. |CHROME_BROWSER| *must* be the
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// first browser listed. The order here must match those in |process_template|
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (in |MemoryDetails::MemoryDetails()| below).
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(viettrungluu): In the big refactoring (see above), get rid of this order
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// dependence.
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum BrowserType {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(viettrungluu): possibly add more?
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHROME_BROWSER = 0,
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SAFARI_BROWSER,
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FIREFOX_BROWSER,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CAMINO_BROWSER,
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OPERA_BROWSER,
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OMNIWEB_BROWSER,
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MAX_BROWSERS
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} BrowserProcess;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMemoryDetails::MemoryDetails() {
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  static const std::string google_browser_name =
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (Human and process) names of browsers; should match the ordering for
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |BrowserProcess| (i.e., |BrowserType|).
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(viettrungluu): The current setup means that we can't detect both
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Chrome and Chromium at the same time!
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(viettrungluu): Get localized browser names for other browsers
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (crbug.com/25779).
62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  struct {
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const char* name;
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const char* process_name;
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } process_template[MAX_BROWSERS] = {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { google_browser_name.c_str(), chrome::kBrowserProcessExecutableName, },
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    { "Safari", "Safari", },
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    { "Firefox", "firefox-bin", },
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    { "Camino", "Camino", },
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    { "Opera", "Opera", },
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    { "OmniWeb", "OmniWeb", },
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  for (size_t index = 0; index < MAX_BROWSERS; ++index) {
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessData process;
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    process.name = UTF8ToUTF16(process_template[index].name);
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    process.process_name = UTF8ToUTF16(process_template[index].process_name);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    process_data_.push_back(process);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProcessData* MemoryDetails::ChromeBrowser() {
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return &process_data_[CHROME_BROWSER];
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MemoryDetails::CollectProcessData(
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::vector<ProcessMemoryInformation>& child_info) {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This must be run on the file thread to avoid jank (|ProcessInfoSnapshot|
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // runs /bin/ps, which isn't instantaneous).
90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clear old data.
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = 0; index < MAX_BROWSERS; index++)
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    process_data_[index].processes.clear();
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First, we use |NamedProcessIterator| to get the PIDs of the processes we're
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // interested in; we save our results to avoid extra calls to
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |NamedProcessIterator| (for performance reasons) and to avoid additional
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // inconsistencies caused by racing. Then we run |/bin/ps| *once* to get
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // information on those PIDs. Then we used our saved information to iterate
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // over browsers, then over PIDs.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get PIDs of main browser processes.
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<base::ProcessId> pids_by_browser[MAX_BROWSERS];
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<base::ProcessId> all_pids;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = CHROME_BROWSER; index < MAX_BROWSERS; index++) {
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    base::NamedProcessIterator process_it(
10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        UTF16ToUTF8(process_data_[index].process_name), NULL);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (const base::ProcessEntry* entry = process_it.NextProcessEntry()) {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pids_by_browser[index].push_back(entry->pid());
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      all_pids.push_back(entry->pid());
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get PIDs of helpers.
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<base::ProcessId> helper_pids;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::NamedProcessIterator helper_it(chrome::kHelperProcessExecutableName,
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         NULL);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (const base::ProcessEntry* entry = helper_it.NextProcessEntry()) {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      helper_pids.push_back(entry->pid());
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      all_pids.push_back(entry->pid());
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Capture information about the processes we're interested in.
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessInfoSnapshot process_info;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  process_info.Sample(all_pids);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handle the other processes first.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t index = CHROME_BROWSER + 1; index < MAX_BROWSERS; index++) {
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (std::vector<base::ProcessId>::const_iterator it =
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         pids_by_browser[index].begin();
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         it != pids_by_browser[index].end(); ++it) {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ProcessMemoryInformation info;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      info.pid = *it;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      info.type = ChildProcessInfo::UNKNOWN_PROCESS;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Try to get version information. To do this, we need first to get the
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // executable's name (we can only believe |proc_info.command| if it looks
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // like an absolute path). Then we need strip the executable's name back
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // to the bundle's name. And only then can we try to get the version.
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      scoped_ptr<FileVersionInfo> version_info;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ProcessInfoSnapshot::ProcInfoEntry proc_info;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (process_info.GetProcInfo(info.pid, &proc_info)) {
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (proc_info.command.length() > 1 && proc_info.command[0] == '/') {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          FilePath bundle_name =
1493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen              base::mac::GetAppBundlePath(FilePath(proc_info.command));
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          if (!bundle_name.empty()) {
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            version_info.reset(FileVersionInfo::CreateFileVersionInfo(
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                bundle_name));
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          }
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (version_info.get()) {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.product_name = version_info->product_name();
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.version = version_info->product_version();
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.product_name = process_data_[index].name;
16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        info.version = string16();
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Memory info.
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      process_info.GetCommittedKBytesOfPID(info.pid, &info.committed);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      process_info.GetWorkingSetKBytesOfPID(info.pid, &info.working_set);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Add the process info to our list.
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      process_data_[index].processes.push_back(info);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Collect data about Chrome/Chromium.
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<base::ProcessId>::const_iterator it =
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       pids_by_browser[CHROME_BROWSER].begin();
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != pids_by_browser[CHROME_BROWSER].end(); ++it) {
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CollectProcessDataChrome(child_info, *it, process_info);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And collect data about the helpers.
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<base::ProcessId>::const_iterator it = helper_pids.begin();
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != helper_pids.end(); ++it) {
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CollectProcessDataChrome(child_info, *it, process_info);
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Finally return to the browser thread.
187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnUIThread));
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MemoryDetails::CollectProcessDataChrome(
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<ProcessMemoryInformation>& child_info,
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::ProcessId pid,
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const ProcessInfoSnapshot& process_info) {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessMemoryInformation info;
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info.pid = pid;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (info.pid == base::GetCurrentProcId())
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.type = ChildProcessInfo::BROWSER_PROCESS;
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.type = ChildProcessInfo::UNKNOWN_PROCESS;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  chrome::VersionInfo version_info;
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (version_info.is_valid()) {
20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    info.product_name = ASCIIToUTF16(version_info.Name());
20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    info.version = ASCIIToUTF16(version_info.Version());
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.product_name = process_data_[CHROME_BROWSER].name;
20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    info.version = string16();
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check if this is one of the child processes whose data we collected
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on the IO thread, and if so copy over that data.
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t child = 0; child < child_info.size(); child++) {
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (child_info[child].pid == info.pid) {
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      info.titles = child_info[child].titles;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      info.type = child_info[child].type;
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Memory info.
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  process_info.GetCommittedKBytesOfPID(info.pid, &info.committed);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  process_info.GetWorkingSetKBytesOfPID(info.pid, &info.working_set);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the process info to our list.
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  process_data_[CHROME_BROWSER].processes.push_back(info);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
229