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; 9029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch for (int i = 0; i < model->GetTabCount(); ++i) { 9129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch content::WebContents* tab_web_contents = model->GetWebContentsAt(i); 9229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch if (tab_web_contents) 9329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch web_contents->insert(tab_web_contents); 9429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch } 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#else 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (TabContentsIterator iter; !iter.done(); iter.Next()) 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) web_contents->insert(*iter); 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Add all the prerender pages. 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Profile*> profiles( 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) g_browser_process->profile_manager()->GetLoadedProfiles()); 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < profiles.size(); ++i) { 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender::PrerenderManager* prerender_manager = 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender::PrerenderManagerFactory::GetForProfile(profiles[i]); 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!prerender_manager) 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue; 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<content::WebContents*> contentses = 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) prerender_manager->GetAllPrerenderingContents(); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents->insert(contentses.begin(), contentses.end()); 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 112c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(ENABLE_FULL_PRINTING) 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Add all the pages being background printed. 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) printing::BackgroundPrintingManager* printing_manager = 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) g_browser_process->background_printing_manager(); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<content::WebContents*> printing_contents = 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printing_manager->CurrentContentSet(); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents->insert(printing_contents.begin(), printing_contents.end()); 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass RendererDetails : public content::NotificationObserver { 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch typedef base::Callback<void(const base::ProcessId pid, 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t v8_allocated, 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t v8_used)> V8DataCallback; 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit RendererDetails(const V8DataCallback& callback) 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : callback_(callback) { 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch registrar_.Add(this, chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED, 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::NotificationService::AllSources()); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~RendererDetails() {} 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void Request() { 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (std::set<content::WebContents*>::iterator iter = web_contents_.begin(); 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch iter != web_contents_.end(); ++iter) 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (*iter)->GetRenderViewHost()->Send(new ChromeViewMsg_GetV8HeapStats); 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void AddWebContents(content::WebContents* content) { 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_contents_.insert(content); 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void Clear() { 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_contents_.clear(); 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void RemoveWebContents(base::ProcessId) { 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // We don't have to detect which content is the caller of this method. 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!web_contents_.empty()) 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_contents_.erase(web_contents_.begin()); 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int IsClean() { 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return web_contents_.empty(); 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // NotificationObserver: 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void Observe(int type, 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const content::NotificationSource& source, 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const content::NotificationDetails& details) OVERRIDE { 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::ProcessId* pid = 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::Source<const base::ProcessId>(source).ptr(); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const ChromeRenderMessageFilter::V8HeapStatsDetails* v8_heap = 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::Details<const ChromeRenderMessageFilter::V8HeapStatsDetails>( 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch details).ptr(); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback_.Run(*pid, 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch v8_heap->v8_memory_allocated(), 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch v8_heap->v8_memory_used()); 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch V8DataCallback callback_; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch content::NotificationRegistrar registrar_; 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::set<content::WebContents*> web_contents_; // This class does not own 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(RendererDetails); 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochMemoryInternalsProxy::MemoryInternalsProxy() 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : information_(new base::DictionaryValue()), 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch renderer_details_(new RendererDetails( 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&MemoryInternalsProxy::OnRendererAvailable, this))) {} 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MemoryInternalsProxy::Attach(MemoryInternalsHandler* handler) { 189e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) handler_ = handler; 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MemoryInternalsProxy::Detach() { 194e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) handler_ = NULL; 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::StartFetch(const base::ListValue* list) { 199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Clear previous information before fetching new information. 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch information_->Clear(); 2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<ProcessDetails> process(new ProcessDetails( 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&MemoryInternalsProxy::OnProcessAvailable, this))); 2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->StartFetch(MemoryDetails::SKIP_USER_METRICS); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MemoryInternalsProxy::~MemoryInternalsProxy() {} 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::RequestRendererDetails() { 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->Clear(); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_ANDROID) 2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (TabModelList::const_iterator iter = TabModelList::begin(); 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter != TabModelList::end(); ++iter) { 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TabModel* model = *iter; 21729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch for (int i = 0; i < model->GetTabCount(); ++i) { 21829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch content::WebContents* tab_web_contents = model->GetWebContentsAt(i); 21929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch if (tab_web_contents) 22029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch renderer_details_->AddWebContents(tab_web_contents); 22129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch } 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (TabContentsIterator iter; !iter.done(); iter.Next()) 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->AddWebContents(*iter); 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->Request(); 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::OnProcessAvailable(const ProcessData& browser) { 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* process_info = new base::ListValue(); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* extension_info = new base::ListValue(); 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch information_->Set("processes", process_info); 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch information_->Set("extensions", extension_info); 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (PMIIterator iter = browser.processes.begin(); 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter != browser.processes.end(); ++iter) { 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* process = new base::DictionaryValue(); 2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION) 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch extension_info->Append(process); 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_info->Append(process); 2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // From MemoryDetails. 2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("pid", iter->pid); 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetString("type", 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ProcessMemoryInformation::GetFullTypeNameInEnglish( 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter->process_type, iter->renderer_type)); 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("memory_private", iter->working_set.priv); 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* titles = new base::ListValue(); 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->Set("titles", titles); 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (size_t i = 0; i < iter->titles.size(); ++i) 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch titles->AppendString(iter->titles[i]); 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::set<content::WebContents*> web_contents; 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetAllWebContents(&web_contents); 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ConvertTabsInformation(web_contents, process_info); 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RequestRendererDetails(); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::OnRendererAvailable(const base::ProcessId pid, 2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const size_t v8_allocated, 2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const size_t v8_used) { 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Do not update while no renderers are registered. 2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (renderer_details_->IsClean()) 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* processes; 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!information_->GetList("processes", &processes)) 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const size_t size = processes->GetSize(); 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < size; ++i) { 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* process; 278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch processes->GetDictionary(i, &process); 279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int id; 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!process->GetInteger("pid", &id) || id != static_cast<int>(pid)) 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Convert units from Bytes to KiB. 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("v8_alloc", v8_allocated / 1024); 2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process->SetInteger("v8_used", v8_used / 1024); 285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch renderer_details_->RemoveWebContents(pid); 289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (renderer_details_->IsClean()) 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FinishCollection(); 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void MemoryInternalsProxy::ConvertTabsInformation( 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::set<content::WebContents*>& web_contents, 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* processes) { 296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (std::set<content::WebContents*>::const_iterator 297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter = web_contents.begin(); iter != web_contents.end(); ++iter) { 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::WebContents* web = *iter; 29929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch content::RenderProcessHost* process_host = web->GetRenderProcessHost(); 30029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch if (!process_host) 30129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch continue; 302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Find which process renders the web contents. 30429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch const base::ProcessId pid = base::GetProcId(process_host->GetHandle()); 305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* process = FindProcessFromPid(processes, pid); 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!process) 307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue; 308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Prepare storage to register navigation histories. 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* tabs; 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!process->GetList("history", &tabs)) { 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tabs = new base::ListValue(); 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) process->Set("history", tabs); 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* tab = new base::DictionaryValue(); 317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tabs->Append(tab); 318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::ListValue* histories = new base::ListValue(); 320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tab->Set("history", histories); 321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 322a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const content::NavigationController& controller = web->GetController(); 323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const int entry_size = controller.GetEntryCount(); 324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (int i = 0; i < entry_size; ++i) { 325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::NavigationEntry *entry = controller.GetEntryAtIndex(i); 326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::DictionaryValue* history = new base::DictionaryValue(); 327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) histories->Append(history); 328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history->SetString("url", entry->GetURL().spec()); 329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history->SetString("title", entry->GetTitle()); 330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) history->SetInteger("time", (base::Time::Now() - 331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) entry->GetTimestamp()).InSeconds()); 332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tab->SetInteger("index", controller.GetCurrentEntryIndex()); 334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryInternalsProxy::FinishCollection() { 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch information_->SetInteger("uptime", base::SysInfo::Uptime()); 339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch information_->SetString("os", base::SysInfo::OperatingSystemName()); 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch information_->SetString("os_version", 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::SysInfo::OperatingSystemVersion()); 342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", *information_); 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MemoryInternalsProxy::CallJavaScriptFunctionOnUIThread( 3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& function, const base::Value& args) { 348e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::vector<const base::Value*> args_vector(1, &args); 351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 update = 352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::WebUI::GetJavascriptCall(function, args_vector); 3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Don't forward updates to a destructed UI. 3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (handler_) 3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch handler_->OnUpdate(update); 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 357