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