memory_internals_proxy.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright 2013 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. 4 5#include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h" 6 7#include <string> 8#include <vector> 9 10#include "base/bind.h" 11#include "base/strings/string16.h" 12#include "base/strings/string_number_conversions.h" 13#include "base/strings/stringprintf.h" 14#include "base/strings/utf_string_conversions.h" 15#include "base/sys_info.h" 16#include "base/values.h" 17#include "chrome/browser/browser_process.h" 18#include "chrome/browser/defaults.h" 19#include "chrome/browser/extensions/extension_service.h" 20#include "chrome/browser/extensions/extension_system.h" 21#include "chrome/browser/memory_details.h" 22#include "chrome/browser/profiles/profile.h" 23#include "chrome/browser/profiles/profile_manager.h" 24#include "chrome/browser/ui/webui/memory_internals/memory_internals_handler.h" 25#include "chrome/common/extensions/extension.h" 26#include "chrome/common/extensions/extension_set.h" 27#include "content/public/browser/url_data_source.h" 28#include "content/public/browser/web_ui.h" 29#include "grit/chromium_strings.h" 30#include "ui/base/l10n/l10n_util.h" 31#include "ui/webui/jstemplate_builder.h" 32#include "ui/webui/web_ui_util.h" 33 34using content::BrowserThread; 35 36namespace { 37 38class BrowserProcessDetails : public MemoryDetails { 39 public: 40 typedef base::Callback<void(const ProcessData&)> DataCallback; 41 explicit BrowserProcessDetails(const DataCallback& callback) 42 : callback_(callback) {} 43 virtual void OnDetailsAvailable() OVERRIDE { 44 const std::vector<ProcessData>& browser_processes = processes(); 45 // [0] means Chrome. 46 callback_.Run(browser_processes[0]); 47 } 48 49 private: 50 virtual ~BrowserProcessDetails() {} 51 52 DataCallback callback_; 53 54 DISALLOW_COPY_AND_ASSIGN(BrowserProcessDetails); 55}; 56 57} // namespace 58 59MemoryInternalsProxy::MemoryInternalsProxy() {} 60 61void MemoryInternalsProxy::Attach(MemoryInternalsHandler* handler) { 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 63 handler_ = handler; 64} 65 66void MemoryInternalsProxy::Detach() { 67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 68 handler_ = NULL; 69} 70 71void MemoryInternalsProxy::GetInfo(const base::ListValue* list) { 72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 73 74 scoped_refptr<BrowserProcessDetails> browsers(new BrowserProcessDetails( 75 base::Bind(&MemoryInternalsProxy::OnDetailsAvailable, this))); 76 browsers->StartFetch(MemoryDetails::SKIP_USER_METRICS); 77} 78 79MemoryInternalsProxy::~MemoryInternalsProxy() {} 80 81void MemoryInternalsProxy::UpdateUIOnUIThread(const string16& update) { 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 83 84 // Don't forward updates to a destructed UI. 85 if (handler_) 86 handler_->OnUpdate(update); 87} 88 89void MemoryInternalsProxy::OnDetailsAvailable(const ProcessData& browser) { 90 base::DictionaryValue details; 91 92 // System information, which is independent from processes. 93 details.SetInteger("uptime", base::SysInfo::Uptime()); 94 details.SetString("os", base::SysInfo::OperatingSystemName()); 95 details.SetString("os_version", base::SysInfo::OperatingSystemVersion()); 96 97 base::ListValue* processes = new ListValue(); 98 base::ListValue* extensions = new ListValue(); 99 details.Set("processes", processes); 100 details.Set("extensions", extensions); 101 for (ProcessMemoryInformationList::const_iterator 102 iter = browser.processes.begin(); 103 iter != browser.processes.end(); ++iter) { 104 base::DictionaryValue* info = new DictionaryValue(); 105 106 // Information from MemoryDetails. 107 info->SetInteger("pid", iter->pid); 108 info->SetString("type", 109 ProcessMemoryInformation::GetFullTypeNameInEnglish( 110 iter->process_type, iter->renderer_type)); 111 info->SetInteger("memory_private", 112 iter->working_set.priv + iter->committed.priv); 113 base::ListValue* titles = new ListValue(); 114 info->Set("titles", titles); 115 for (size_t i = 0; i < iter->titles.size(); ++i) 116 titles->AppendString(iter->titles[i]); 117 118 if (iter->process_type == content::PROCESS_TYPE_RENDERER && 119 iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION) 120 extensions->Append(info); 121 else 122 processes->Append(info); 123 } 124 125 CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", &details); 126} 127 128void MemoryInternalsProxy::CallJavaScriptFunctionOnUIThread( 129 const std::string& function, base::Value* args) { 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 131 132 std::vector<const base::Value*> args_vector; 133 args_vector.push_back(args); 134 string16 update = content::WebUI::GetJavascriptCall(function, args_vector); 135 UpdateUIOnUIThread(update); 136} 137