memory_internals_proxy.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <set> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/sys_info.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/memory_details.h" 18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h" 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager_factory.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/profiles/profile.h" 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/profiles/profile_manager.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/renderer_host/chrome_render_message_filter.h" 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/ui/android/tab_model/tab_model.h" 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/ui/android/tab_model/tab_model_list.h" 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/webui/memory_internals/memory_internals_handler.h" 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/render_messages.h" 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_observer.h" 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_registrar.h" 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/notification_service.h" 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/render_view_host.h" 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/web_contents.h" 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/web_ui.h" 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(ENABLE_FULL_PRINTING) 41c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#include "chrome/browser/printing/background_printing_manager.h" 42c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif 43c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using content::BrowserThread; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class Profile; 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ProcessDetails : public MemoryDetails { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef base::Callback<void(const ProcessData&)> DataCallback; 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit ProcessDetails(const DataCallback& callback) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : callback_(callback) {} 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // MemoryDetails: 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnDetailsAvailable() OVERRIDE { 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<ProcessData>& browser_processes = processes(); 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // [0] means Chrome. 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_.Run(browser_processes[0]); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~ProcessDetails() {} 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DataCallback callback_; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(ProcessDetails); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::DictionaryValue* FindProcessFromPid(base::ListValue* processes, 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ProcessId pid) { 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const size_t n = processes->GetSize(); 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < n; ++i) { 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* process; 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!processes->GetDictionary(i, &process)) 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return NULL; 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int id; 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (process->GetInteger("pid", &id) && id == static_cast<int>(pid)) 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return process; 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return NULL; 82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void GetAllWebContents(std::set<content::WebContents*>* web_contents) { 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Add all the existing WebContentses. 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_ANDROID) 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (TabModelList::const_iterator iter = TabModelList::begin(); 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != TabModelList::end(); ++iter) { 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) TabModel* model = *iter; 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (int i = 0; i < model->GetTabCount(); ++i) 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) web_contents->insert(model->GetWebContentsAt(i)); 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#else 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (TabContentsIterator iter; !iter.done(); iter.Next()) 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) web_contents->insert(*iter); 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Add all the prerender pages. 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Profile*> profiles( 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) g_browser_process->profile_manager()->GetLoadedProfiles()); 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < profiles.size(); ++i) { 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender::PrerenderManager* prerender_manager = 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender::PrerenderManagerFactory::GetForProfile(profiles[i]); 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!prerender_manager) 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue; 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<content::WebContents*> contentses = 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender_manager->GetAllPrerenderingContents(); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents->insert(contentses.begin(), contentses.end()); 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 109c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(ENABLE_FULL_PRINTING) 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Add all the pages being background printed. 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) printing::BackgroundPrintingManager* printing_manager = 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) g_browser_process->background_printing_manager(); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<content::WebContents*> printing_contents = 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing_manager->CurrentContentSet(); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents->insert(printing_contents.begin(), printing_contents.end()); 116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass RendererDetails : public content::NotificationObserver { 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch typedef base::Callback<void(const base::ProcessId pid, 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t v8_allocated, 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t v8_used)> V8DataCallback; 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit RendererDetails(const V8DataCallback& callback) 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : callback_(callback) { 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch registrar_.Add(this, chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED, 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::NotificationService::AllSources()); 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~RendererDetails() {} 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void Request() { 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (std::set<content::WebContents*>::iterator iter = web_contents_.begin(); 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch iter != web_contents_.end(); ++iter) 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*iter)->GetRenderViewHost()->Send(new ChromeViewMsg_GetV8HeapStats); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void AddWebContents(content::WebContents* content) { 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_contents_.insert(content); 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void Clear() { 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_contents_.clear(); 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void RemoveWebContents(base::ProcessId) { 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We don't have to detect which content is the caller of this method. 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!web_contents_.empty()) 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_contents_.erase(web_contents_.begin()); 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int IsClean() { 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return web_contents_.empty(); 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // NotificationObserver: 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void Observe(int type, 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const content::NotificationSource& source, 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const content::NotificationDetails& details) OVERRIDE { 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::ProcessId* pid = 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::Source<const base::ProcessId>(source).ptr(); 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const ChromeRenderMessageFilter::V8HeapStatsDetails* v8_heap = 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::Details<const ChromeRenderMessageFilter::V8HeapStatsDetails>( 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch details).ptr(); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback_.Run(*pid, 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch v8_heap->v8_memory_allocated(), 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch v8_heap->v8_memory_used()); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch V8DataCallback callback_; 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::NotificationRegistrar registrar_; 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::set<content::WebContents*> web_contents_; // This class does not own 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(RendererDetails); 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMemoryInternalsProxy::MemoryInternalsProxy() 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : information_(new base::DictionaryValue()), 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch renderer_details_(new RendererDetails( 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&MemoryInternalsProxy::OnRendererAvailable, this))) {} 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MemoryInternalsProxy::Attach(MemoryInternalsHandler* handler) { 186e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) handler_ = handler; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MemoryInternalsProxy::Detach() { 191e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) handler_ = NULL; 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::StartFetch(const base::ListValue* list) { 196e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Clear previous information before fetching new information. 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch information_->Clear(); 2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<ProcessDetails> process(new ProcessDetails( 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&MemoryInternalsProxy::OnProcessAvailable, this))); 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->StartFetch(MemoryDetails::SKIP_USER_METRICS); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MemoryInternalsProxy::~MemoryInternalsProxy() {} 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::RequestRendererDetails() { 2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->Clear(); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_ANDROID) 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (TabModelList::const_iterator iter = TabModelList::begin(); 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter != TabModelList::end(); ++iter) { 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TabModel* model = *iter; 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int i = 0; i < model->GetTabCount(); ++i) 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->AddWebContents(model->GetWebContentsAt(i)); 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (TabContentsIterator iter; !iter.done(); iter.Next()) 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->AddWebContents(*iter); 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->Request(); 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::OnProcessAvailable(const ProcessData& browser) { 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* process_info = new base::ListValue(); 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* extension_info = new base::ListValue(); 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch information_->Set("processes", process_info); 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch information_->Set("extensions", extension_info); 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (PMIIterator iter = browser.processes.begin(); 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter != browser.processes.end(); ++iter) { 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* process = new base::DictionaryValue(); 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION) 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch extension_info->Append(process); 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_info->Append(process); 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // From MemoryDetails. 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("pid", iter->pid); 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetString("type", 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ProcessMemoryInformation::GetFullTypeNameInEnglish( 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter->process_type, iter->renderer_type)); 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("memory_private", iter->working_set.priv); 2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* titles = new base::ListValue(); 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->Set("titles", titles); 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (size_t i = 0; i < iter->titles.size(); ++i) 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch titles->AppendString(iter->titles[i]); 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::set<content::WebContents*> web_contents; 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetAllWebContents(&web_contents); 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ConvertTabsInformation(web_contents, process_info); 254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RequestRendererDetails(); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::OnRendererAvailable(const base::ProcessId pid, 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const size_t v8_allocated, 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const size_t v8_used) { 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Do not update while no renderers are registered. 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (renderer_details_->IsClean()) 2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* processes; 266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!information_->GetList("processes", &processes)) 267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t size = processes->GetSize(); 270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < size; ++i) { 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* process; 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch processes->GetDictionary(i, &process); 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int id; 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!process->GetInteger("pid", &id) || id != static_cast<int>(pid)) 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Convert units from Bytes to KiB. 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("v8_alloc", v8_allocated / 1024); 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("v8_used", v8_used / 1024); 279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->RemoveWebContents(pid); 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (renderer_details_->IsClean()) 2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FinishCollection(); 285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MemoryInternalsProxy::ConvertTabsInformation( 288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::set<content::WebContents*>& web_contents, 289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* processes) { 290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (std::set<content::WebContents*>::const_iterator 291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter = web_contents.begin(); iter != web_contents.end(); ++iter) { 292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::WebContents* web = *iter; 293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::ProcessId pid = base::GetProcId( 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) web->GetRenderProcessHost()->GetHandle()); 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Find which process renders the web contents. 297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* process = FindProcessFromPid(processes, pid); 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!process) 299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue; 300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Prepare storage to register navigation histories. 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* tabs; 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!process->GetList("history", &tabs)) { 304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tabs = new base::ListValue(); 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) process->Set("history", tabs); 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* tab = new base::DictionaryValue(); 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tabs->Append(tab); 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* histories = new base::ListValue(); 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tab->Set("history", histories); 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const content::NavigationController& controller = web->GetController(); 315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const int entry_size = controller.GetEntryCount(); 316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (int i = 0; i < entry_size; ++i) { 317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::NavigationEntry *entry = controller.GetEntryAtIndex(i); 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* history = new base::DictionaryValue(); 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) histories->Append(history); 320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history->SetString("url", entry->GetURL().spec()); 321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history->SetString("title", entry->GetTitle()); 322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history->SetInteger("time", (base::Time::Now() - 323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) entry->GetTimestamp()).InSeconds()); 324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tab->SetInteger("index", controller.GetCurrentEntryIndex()); 326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::FinishCollection() { 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch information_->SetInteger("uptime", base::SysInfo::Uptime()); 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch information_->SetString("os", base::SysInfo::OperatingSystemName()); 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch information_->SetString("os_version", 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::SysInfo::OperatingSystemVersion()); 334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", *information_); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MemoryInternalsProxy::CallJavaScriptFunctionOnUIThread( 3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& function, const base::Value& args) { 340e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::vector<const base::Value*> args_vector(1, &args); 343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 update = 344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::WebUI::GetJavascriptCall(function, args_vector); 3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Don't forward updates to a destructed UI. 3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (handler_) 3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch handler_->OnUpdate(update); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 349