15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/memory_details.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h" 15bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/process_iterator.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/process_info_snapshot.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/chromium_strings.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/process_type.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(viettrungluu): Many of the TODOs below are subsumed by a general need to 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// refactor the about:memory code (not just on Mac, but probably on other 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// platforms as well). I've filed crbug.com/25456. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Known browsers which we collect details for. |CHROME_BROWSER| *must* be the 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// first browser listed. The order here must match those in |process_template| 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (in |MemoryDetails::MemoryDetails()| below). 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(viettrungluu): In the big refactoring (see above), get rid of this order 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dependence. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BrowserType { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(viettrungluu): possibly add more? 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHROME_BROWSER = 0, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SAFARI_BROWSER, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FIREFOX_BROWSER, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAMINO_BROWSER, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPERA_BROWSER, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OMNIWEB_BROWSER, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAX_BROWSERS 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} BrowserProcess; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MemoryDetails::MemoryDetails() 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : user_metrics_mode_(UPDATE_USER_METRICS), 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memory_growth_tracker_(NULL) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string google_browser_name = 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF8(IDS_PRODUCT_NAME); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (Human and process) names of browsers; should match the ordering for 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |BrowserProcess| (i.e., |BrowserType|). 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(viettrungluu): The current setup means that we can't detect both 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome and Chromium at the same time! 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(viettrungluu): Get localized browser names for other browsers 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (crbug.com/25779). 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* process_name; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } process_template[MAX_BROWSERS] = { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { google_browser_name.c_str(), chrome::kBrowserProcessExecutableName, }, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Safari", "Safari", }, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Firefox", "firefox-bin", }, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Camino", "Camino", }, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Opera", "Opera", }, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "OmniWeb", "OmniWeb", }, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = 0; index < MAX_BROWSERS; ++index) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessData process; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process.name = base::UTF8ToUTF16(process_template[index].name); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process.process_name = 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(process_template[index].process_name); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_data_.push_back(process); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData* MemoryDetails::ChromeBrowser() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &process_data_[CHROME_BROWSER]; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::CollectProcessData( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ProcessMemoryInformation>& child_info) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must be run on the file thread to avoid jank (|ProcessInfoSnapshot| 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // runs /bin/ps, which isn't instantaneous). 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear old data. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = 0; index < MAX_BROWSERS; index++) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_data_[index].processes.clear(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, we use |NamedProcessIterator| to get the PIDs of the processes we're 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // interested in; we save our results to avoid extra calls to 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |NamedProcessIterator| (for performance reasons) and to avoid additional 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inconsistencies caused by racing. Then we run |/bin/ps| *once* to get 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information on those PIDs. Then we used our saved information to iterate 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // over browsers, then over PIDs. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get PIDs of main browser processes. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::ProcessId> pids_by_browser[MAX_BROWSERS]; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::ProcessId> all_pids; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = CHROME_BROWSER; index < MAX_BROWSERS; index++) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::NamedProcessIterator process_it( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF16ToUTF8(process_data_[index].process_name), NULL); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (const base::ProcessEntry* entry = process_it.NextProcessEntry()) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pids_by_browser[index].push_back(entry->pid()); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_pids.push_back(entry->pid()); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The helper might show up as these different flavors depending on the 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // executable flags required. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> helper_names; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_names.push_back(chrome::kHelperProcessExecutableName); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const char* const* suffix = chrome::kHelperFlavorSuffixes; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *suffix; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++suffix) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string helper_name = chrome::kHelperProcessExecutableName; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_name.append(1, ' '); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_name.append(*suffix); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_names.push_back(helper_name); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get PIDs of helpers. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::ProcessId> helper_pids; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < helper_names.size(); ++i) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string helper_name = helper_names[i]; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::NamedProcessIterator helper_it(helper_name, NULL); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (const base::ProcessEntry* entry = helper_it.NextProcessEntry()) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_pids.push_back(entry->pid()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_pids.push_back(entry->pid()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Capture information about the processes we're interested in. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessInfoSnapshot process_info; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_info.Sample(all_pids); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle the other processes first. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = CHROME_BROWSER + 1; index < MAX_BROWSERS; index++) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<base::ProcessId>::const_iterator it = 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pids_by_browser[index].begin(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pids_by_browser[index].end(); ++it) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessMemoryInformation info; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.pid = *it; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.process_type = content::PROCESS_TYPE_UNKNOWN; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to get version information. To do this, we need first to get the 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // executable's name (we can only believe |proc_info.command| if it looks 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // like an absolute path). Then we need strip the executable's name back 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the bundle's name. And only then can we try to get the version. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FileVersionInfo> version_info; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessInfoSnapshot::ProcInfoEntry proc_info; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_info.GetProcInfo(info.pid, &proc_info)) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proc_info.command.length() > 1 && proc_info.command[0] == '/') { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath bundle_name = 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::mac::GetAppBundlePath(base::FilePath(proc_info.command)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bundle_name.empty()) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_info.reset(FileVersionInfo::CreateFileVersionInfo( 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bundle_name)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version_info.get()) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.product_name = version_info->product_name(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.version = version_info->product_version(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.product_name = process_data_[index].name; 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) info.version = base::string16(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Memory info. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_info.GetCommittedKBytesOfPID(info.pid, &info.committed); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_info.GetWorkingSetKBytesOfPID(info.pid, &info.working_set); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the process info to our list. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_data_[index].processes.push_back(info); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Collect data about Chrome/Chromium. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<base::ProcessId>::const_iterator it = 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pids_by_browser[CHROME_BROWSER].begin(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pids_by_browser[CHROME_BROWSER].end(); ++it) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollectProcessDataChrome(child_info, *it, process_info); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And collect data about the helpers. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<base::ProcessId>::const_iterator it = helper_pids.begin(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != helper_pids.end(); ++it) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CollectProcessDataChrome(child_info, *it, process_info); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally return to the browser thread. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::CollectProcessDataChrome( 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<ProcessMemoryInformation>& child_info, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessId pid, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProcessInfoSnapshot& process_info) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessMemoryInformation info; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.pid = pid; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info.pid == base::GetCurrentProcId()) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.process_type = content::PROCESS_TYPE_BROWSER; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.process_type = content::PROCESS_TYPE_UNKNOWN; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo version_info; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version_info.is_valid()) { 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.product_name = base::ASCIIToUTF16(version_info.Name()); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.version = base::ASCIIToUTF16(version_info.Version()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.product_name = process_data_[CHROME_BROWSER].name; 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) info.version = base::string16(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if this is one of the child processes whose data we collected 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the IO thread, and if so copy over that data. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t child = 0; child < child_info.size(); child++) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child_info[child].pid == info.pid) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.titles = child_info[child].titles; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.process_type = child_info[child].process_type; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Memory info. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_info.GetCommittedKBytesOfPID(info.pid, &info.committed); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_info.GetWorkingSetKBytesOfPID(info.pid, &info.working_set); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the process info to our list. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_data_[CHROME_BROWSER].processes.push_back(info); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 243