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