Fix build break
[chromium-blink-merge.git] / chrome / browser / memory_details_win.cc
blob30cf64fec1b231e27d08bf9dc98356c7f14ea4c7
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 <psapi.h>
9 #include "base/bind.h"
10 #include "base/file_version_info.h"
11 #include "base/files/file_path.h"
12 #include "base/string_util.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/win/scoped_handle.h"
15 #include "base/win/windows_version.h"
16 #include "chrome/common/chrome_version_info.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/common/process_type.h"
20 #include "grit/chromium_strings.h"
21 #include "ui/base/l10n/l10n_util.h"
23 using content::BrowserThread;
25 // Known browsers which we collect details for.
26 enum {
27 CHROME_BROWSER = 0,
28 CHROME_NACL_PROCESS,
29 IE_BROWSER,
30 FIREFOX_BROWSER,
31 OPERA_BROWSER,
32 SAFARI_BROWSER,
33 IE_64BIT_BROWSER,
34 KONQUEROR_BROWSER,
35 MAX_BROWSERS
36 } BrowserProcess;
38 MemoryDetails::MemoryDetails()
39 : user_metrics_mode_(UPDATE_USER_METRICS) {
40 static const std::wstring google_browser_name =
41 UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
42 struct {
43 const wchar_t* name;
44 const wchar_t* process_name;
45 } process_template[MAX_BROWSERS] = {
46 { google_browser_name.c_str(), L"chrome.exe", },
47 { google_browser_name.c_str(), L"nacl64.exe", },
48 { L"IE", L"iexplore.exe", },
49 { L"Firefox", L"firefox.exe", },
50 { L"Opera", L"opera.exe", },
51 { L"Safari", L"safari.exe", },
52 { L"IE (64bit)", L"iexplore.exe", },
53 { L"Konqueror", L"konqueror.exe", },
56 for (int index = 0; index < MAX_BROWSERS; ++index) {
57 ProcessData process;
58 process.name = process_template[index].name;
59 process.process_name = process_template[index].process_name;
60 process_data_.push_back(process);
64 ProcessData* MemoryDetails::ChromeBrowser() {
65 return &process_data_[CHROME_BROWSER];
68 void MemoryDetails::CollectProcessData(
69 const std::vector<ProcessMemoryInformation>& child_info) {
70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
72 // Clear old data.
73 for (unsigned int index = 0; index < process_data_.size(); index++)
74 process_data_[index].processes.clear();
76 base::win::OSInfo::WindowsArchitecture windows_architecture =
77 base::win::OSInfo::GetInstance()->architecture();
79 base::win::ScopedHandle snapshot(
80 ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
81 PROCESSENTRY32 process_entry = {sizeof(PROCESSENTRY32)};
82 if (!snapshot.Get()) {
83 LOG(ERROR) << "CreateToolhelp32Snaphot failed: " << GetLastError();
84 return;
86 if (!::Process32First(snapshot, &process_entry)) {
87 LOG(ERROR) << "Process32First failed: " << GetLastError();
88 return;
90 do {
91 base::ProcessId pid = process_entry.th32ProcessID;
92 base::win::ScopedHandle process_handle(::OpenProcess(
93 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
94 if (!process_handle.Get())
95 continue;
96 bool is_64bit_process =
97 ((windows_architecture == base::win::OSInfo::X64_ARCHITECTURE) ||
98 (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE)) &&
99 (base::win::OSInfo::GetWOW64StatusForProcess(process_handle) ==
100 base::win::OSInfo::WOW64_DISABLED);
101 for (unsigned int index2 = 0; index2 < process_data_.size(); index2++) {
102 if (_wcsicmp(process_data_[index2].process_name.c_str(),
103 process_entry.szExeFile) != 0)
104 continue;
105 if (index2 == IE_BROWSER && is_64bit_process)
106 continue; // Should use IE_64BIT_BROWSER
107 // Get Memory Information.
108 ProcessMemoryInformation info;
109 info.pid = pid;
110 if (info.pid == GetCurrentProcessId())
111 info.process_type = content::PROCESS_TYPE_BROWSER;
112 else
113 info.process_type = content::PROCESS_TYPE_UNKNOWN;
115 scoped_ptr<base::ProcessMetrics> metrics;
116 metrics.reset(base::ProcessMetrics::CreateProcessMetrics(process_handle));
117 metrics->GetCommittedKBytes(&info.committed);
118 metrics->GetWorkingSetKBytes(&info.working_set);
120 // Get Version Information.
121 TCHAR name[MAX_PATH];
122 if (index2 == CHROME_BROWSER || index2 == CHROME_NACL_PROCESS) {
123 chrome::VersionInfo version_info;
124 if (version_info.is_valid())
125 info.version = ASCIIToWide(version_info.Version());
126 // Check if this is one of the child processes whose data we collected
127 // on the IO thread, and if so copy over that data.
128 for (size_t child = 0; child < child_info.size(); child++) {
129 if (child_info[child].pid != info.pid)
130 continue;
131 info.titles = child_info[child].titles;
132 info.process_type = child_info[child].process_type;
133 break;
135 } else if (GetModuleFileNameEx(process_handle, NULL, name,
136 MAX_PATH - 1)) {
137 std::wstring str_name(name);
138 scoped_ptr<FileVersionInfo> version_info(
139 FileVersionInfo::CreateFileVersionInfo(base::FilePath(str_name)));
140 if (version_info != NULL) {
141 info.version = version_info->product_version();
142 info.product_name = version_info->product_name();
146 // Add the process info to our list.
147 if (index2 == CHROME_NACL_PROCESS) {
148 // Add NaCl processes to Chrome's list
149 process_data_[CHROME_BROWSER].processes.push_back(info);
150 } else {
151 process_data_[index2].processes.push_back(info);
153 break;
155 } while (::Process32Next(snapshot, &process_entry));
157 // Finally return to the browser thread.
158 BrowserThread::PostTask(
159 BrowserThread::UI, FROM_HERE,
160 base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));