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