Index: chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc |
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc |
deleted file mode 100644 |
index d69aa2d9b39bdf52895fcb0467adf01d3b8ea0f7..0000000000000000000000000000000000000000 |
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc |
+++ /dev/null |
@@ -1,371 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h" |
- |
-#include <map> |
-#include <set> |
-#include <string> |
-#include <utility> |
-#include <vector> |
- |
-#include "base/bind.h" |
-#include "base/macros.h" |
-#include "base/memory/linked_ptr.h" |
-#include "base/memory/weak_ptr.h" |
-#include "base/strings/string16.h" |
-#include "base/sys_info.h" |
-#include "base/values.h" |
-#include "chrome/browser/browser_process.h" |
-#include "chrome/browser/chrome_notification_types.h" |
-#include "chrome/browser/memory_details.h" |
-#include "chrome/browser/prerender/prerender_manager.h" |
-#include "chrome/browser/prerender/prerender_manager_factory.h" |
-#include "chrome/browser/process_resource_usage.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/profiles/profile_manager.h" |
-#include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
-#include "chrome/browser/ui/android/tab_model/tab_model.h" |
-#include "chrome/browser/ui/android/tab_model/tab_model_list.h" |
-#include "chrome/browser/ui/browser.h" |
-#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
-#include "chrome/browser/ui/webui/memory_internals/memory_internals_handler.h" |
-#include "chrome/common/features.h" |
-#include "content/public/browser/navigation_controller.h" |
-#include "content/public/browser/navigation_entry.h" |
-#include "content/public/browser/render_process_host.h" |
-#include "content/public/browser/render_view_host.h" |
-#include "content/public/browser/web_contents.h" |
-#include "content/public/browser/web_ui.h" |
-#include "content/public/common/service_registry.h" |
- |
-#if defined(ENABLE_PRINT_PREVIEW) |
-#include "chrome/browser/printing/background_printing_manager.h" |
-#endif |
- |
-using content::BrowserThread; |
- |
-class Profile; |
- |
-namespace { |
- |
-class ProcessDetails : public MemoryDetails { |
- public: |
- typedef base::Callback<void(const ProcessData&)> DataCallback; |
- explicit ProcessDetails(const DataCallback& callback) |
- : callback_(callback) {} |
- |
- // MemoryDetails: |
- void OnDetailsAvailable() override { callback_.Run(*ChromeBrowser()); } |
- |
- private: |
- ~ProcessDetails() override {} |
- |
- DataCallback callback_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ProcessDetails); |
-}; |
- |
-base::DictionaryValue* FindProcessFromPid(base::ListValue* processes, |
- base::ProcessId pid) { |
- const size_t n = processes->GetSize(); |
- for (size_t i = 0; i < n; ++i) { |
- base::DictionaryValue* process; |
- if (!processes->GetDictionary(i, &process)) |
- return NULL; |
- int id; |
- if (process->GetInteger("pid", &id) && id == static_cast<int>(pid)) |
- return process; |
- } |
- return NULL; |
-} |
- |
-void GetAllWebContents(std::set<content::WebContents*>* web_contents) { |
- // Add all the existing WebContentses. |
-#if BUILDFLAG(ANDROID_JAVA_UI) |
- for (TabModelList::const_iterator iter = TabModelList::begin(); |
- iter != TabModelList::end(); ++iter) { |
- TabModel* model = *iter; |
- for (int i = 0; i < model->GetTabCount(); ++i) { |
- content::WebContents* tab_web_contents = model->GetWebContentsAt(i); |
- if (tab_web_contents) |
- web_contents->insert(tab_web_contents); |
- } |
- } |
-#else |
- for (TabContentsIterator iter; !iter.done(); iter.Next()) |
- web_contents->insert(*iter); |
-#endif |
- // Add all the prerender pages. |
- std::vector<Profile*> profiles( |
- g_browser_process->profile_manager()->GetLoadedProfiles()); |
- for (size_t i = 0; i < profiles.size(); ++i) { |
- prerender::PrerenderManager* prerender_manager = |
- prerender::PrerenderManagerFactory::GetForProfile(profiles[i]); |
- if (!prerender_manager) |
- continue; |
- const std::vector<content::WebContents*> contentses = |
- prerender_manager->GetAllPrerenderingContents(); |
- web_contents->insert(contentses.begin(), contentses.end()); |
- } |
-#if defined(ENABLE_PRINT_PREVIEW) |
- // Add all the pages being background printed. |
- printing::BackgroundPrintingManager* printing_manager = |
- g_browser_process->background_printing_manager(); |
- std::set<content::WebContents*> printing_contents = |
- printing_manager->CurrentContentSet(); |
- web_contents->insert(printing_contents.begin(), printing_contents.end()); |
-#endif |
-} |
- |
-} // namespace |
- |
-class RendererDetails { |
- public: |
- typedef base::Callback<void(const base::ProcessId pid, |
- const size_t v8_allocated, |
- const size_t v8_used)> V8DataCallback; |
- |
- explicit RendererDetails(const V8DataCallback& callback) |
- : callback_(callback), weak_factory_(this) {} |
- ~RendererDetails() {} |
- |
- void Request() { |
- for (std::set<content::WebContents*>::iterator iter = web_contents_.begin(); |
- iter != web_contents_.end(); ++iter) { |
- auto rph = (*iter)->GetRenderViewHost()->GetProcess(); |
- auto resource_usage = resource_usage_reporters_[(*iter)]; |
- DCHECK(resource_usage.get()); |
- resource_usage->Refresh(base::Bind(&RendererDetails::OnRefreshDone, |
- weak_factory_.GetWeakPtr(), *iter, |
- base::GetProcId(rph->GetHandle()))); |
- } |
- } |
- |
- void AddWebContents(content::WebContents* content) { |
- web_contents_.insert(content); |
- |
- auto rph = content->GetRenderViewHost()->GetProcess(); |
- content::ServiceRegistry* service_registry = rph->GetServiceRegistry(); |
- ResourceUsageReporterPtr service; |
- if (service_registry) |
- service_registry->ConnectToRemoteService(mojo::GetProxy(&service)); |
- resource_usage_reporters_.insert(std::make_pair( |
- content, |
- make_linked_ptr(new ProcessResourceUsage(std::move(service))))); |
- DCHECK_EQ(web_contents_.size(), resource_usage_reporters_.size()); |
- } |
- |
- void Clear() { |
- web_contents_.clear(); |
- resource_usage_reporters_.clear(); |
- weak_factory_.InvalidateWeakPtrs(); |
- } |
- |
- void RemoveWebContents(base::ProcessId) { |
- // This function should only be called once for each WebContents, so this |
- // should be non-empty every time it's called. |
- DCHECK(!web_contents_.empty()); |
- |
- // We don't have to detect which content is the caller of this method. |
- if (!web_contents_.empty()) |
- web_contents_.erase(web_contents_.begin()); |
- } |
- |
- int IsClean() { |
- return web_contents_.empty(); |
- } |
- |
- private: |
- void OnRefreshDone(content::WebContents* content, const base::ProcessId pid) { |
- auto iter = resource_usage_reporters_.find(content); |
- DCHECK(iter != resource_usage_reporters_.end()); |
- linked_ptr<ProcessResourceUsage> usage = iter->second; |
- callback_.Run(pid, usage->GetV8MemoryAllocated(), usage->GetV8MemoryUsed()); |
- } |
- |
- V8DataCallback callback_; |
- std::set<content::WebContents*> web_contents_; // This class does not own |
- std::map<content::WebContents*, linked_ptr<ProcessResourceUsage>> |
- resource_usage_reporters_; |
- |
- base::WeakPtrFactory<RendererDetails> weak_factory_; |
- |
- DISALLOW_COPY_AND_ASSIGN(RendererDetails); |
-}; |
- |
-MemoryInternalsProxy::MemoryInternalsProxy() |
- : information_(new base::DictionaryValue()), |
- renderer_details_(new RendererDetails( |
- base::Bind(&MemoryInternalsProxy::OnRendererAvailable, this))) {} |
- |
-void MemoryInternalsProxy::Attach(MemoryInternalsHandler* handler) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- handler_ = handler; |
-} |
- |
-void MemoryInternalsProxy::Detach() { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- handler_ = NULL; |
-} |
- |
-void MemoryInternalsProxy::StartFetch(const base::ListValue* list) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- |
- // Clear previous information before fetching new information. |
- information_->Clear(); |
- scoped_refptr<ProcessDetails> process(new ProcessDetails( |
- base::Bind(&MemoryInternalsProxy::OnProcessAvailable, this))); |
- process->StartFetch(MemoryDetails::FROM_CHROME_ONLY); |
-} |
- |
-MemoryInternalsProxy::~MemoryInternalsProxy() {} |
- |
-void MemoryInternalsProxy::RequestRendererDetails() { |
- renderer_details_->Clear(); |
- |
-#if BUILDFLAG(ANDROID_JAVA_UI) |
- for (TabModelList::const_iterator iter = TabModelList::begin(); |
- iter != TabModelList::end(); ++iter) { |
- TabModel* model = *iter; |
- for (int i = 0; i < model->GetTabCount(); ++i) { |
- content::WebContents* tab_web_contents = model->GetWebContentsAt(i); |
- if (tab_web_contents) |
- renderer_details_->AddWebContents(tab_web_contents); |
- } |
- } |
-#else |
- for (TabContentsIterator iter; !iter.done(); iter.Next()) |
- renderer_details_->AddWebContents(*iter); |
-#endif |
- |
- renderer_details_->Request(); |
-} |
- |
-void MemoryInternalsProxy::OnProcessAvailable(const ProcessData& browser) { |
- base::ListValue* process_info = new base::ListValue(); |
- base::ListValue* extension_info = new base::ListValue(); |
- information_->Set("processes", process_info); |
- information_->Set("extensions", extension_info); |
- for (PMIIterator iter = browser.processes.begin(); |
- iter != browser.processes.end(); ++iter) { |
- base::DictionaryValue* process = new base::DictionaryValue(); |
- if (iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION) |
- extension_info->Append(process); |
- else |
- process_info->Append(process); |
- |
- // From MemoryDetails. |
- process->SetInteger("pid", iter->pid); |
- process->SetString("type", |
- ProcessMemoryInformation::GetFullTypeNameInEnglish( |
- iter->process_type, iter->renderer_type)); |
- process->SetInteger("memory_private", iter->working_set.priv); |
- |
- base::ListValue* titles = new base::ListValue(); |
- process->Set("titles", titles); |
- for (size_t i = 0; i < iter->titles.size(); ++i) |
- titles->AppendString(iter->titles[i]); |
- } |
- |
- std::set<content::WebContents*> web_contents; |
- GetAllWebContents(&web_contents); |
- ConvertTabsInformation(web_contents, process_info); |
- |
- RequestRendererDetails(); |
-} |
- |
-void MemoryInternalsProxy::OnRendererAvailable(const base::ProcessId pid, |
- const size_t v8_allocated, |
- const size_t v8_used) { |
- // Do not update while no renderers are registered. |
- if (renderer_details_->IsClean()) |
- return; |
- |
- base::ListValue* processes; |
- if (!information_->GetList("processes", &processes)) |
- return; |
- |
- const size_t size = processes->GetSize(); |
- for (size_t i = 0; i < size; ++i) { |
- base::DictionaryValue* process; |
- processes->GetDictionary(i, &process); |
- int id; |
- if (!process->GetInteger("pid", &id) || id != static_cast<int>(pid)) |
- continue; |
- // Convert units from Bytes to KiB. |
- process->SetInteger("v8_alloc", v8_allocated / 1024); |
- process->SetInteger("v8_used", v8_used / 1024); |
- break; |
- } |
- |
- renderer_details_->RemoveWebContents(pid); |
- if (renderer_details_->IsClean()) |
- FinishCollection(); |
-} |
- |
-void MemoryInternalsProxy::ConvertTabsInformation( |
- const std::set<content::WebContents*>& web_contents, |
- base::ListValue* processes) { |
- for (std::set<content::WebContents*>::const_iterator |
- iter = web_contents.begin(); iter != web_contents.end(); ++iter) { |
- content::WebContents* web = *iter; |
- content::RenderProcessHost* process_host = web->GetRenderProcessHost(); |
- if (!process_host) |
- continue; |
- |
- // Find which process renders the web contents. |
- const base::ProcessId pid = base::GetProcId(process_host->GetHandle()); |
- base::DictionaryValue* process = FindProcessFromPid(processes, pid); |
- if (!process) |
- continue; |
- |
- // Prepare storage to register navigation histories. |
- base::ListValue* tabs; |
- if (!process->GetList("history", &tabs)) { |
- tabs = new base::ListValue(); |
- process->Set("history", tabs); |
- } |
- |
- base::DictionaryValue* tab = new base::DictionaryValue(); |
- tabs->Append(tab); |
- |
- base::ListValue* histories = new base::ListValue(); |
- tab->Set("history", histories); |
- |
- const content::NavigationController& controller = web->GetController(); |
- const int entry_size = controller.GetEntryCount(); |
- for (int i = 0; i < entry_size; ++i) { |
- content::NavigationEntry *entry = controller.GetEntryAtIndex(i); |
- base::DictionaryValue* history = new base::DictionaryValue(); |
- histories->Append(history); |
- history->SetString("url", entry->GetURL().spec()); |
- history->SetString("title", entry->GetTitle()); |
- history->SetInteger("time", (base::Time::Now() - |
- entry->GetTimestamp()).InSeconds()); |
- } |
- tab->SetInteger("index", controller.GetCurrentEntryIndex()); |
- } |
-} |
- |
-void MemoryInternalsProxy::FinishCollection() { |
- information_->SetInteger("uptime", base::SysInfo::Uptime().InMilliseconds()); |
- information_->SetString("os", base::SysInfo::OperatingSystemName()); |
- information_->SetString("os_version", |
- base::SysInfo::OperatingSystemVersion()); |
- |
- CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", *information_); |
-} |
- |
-void MemoryInternalsProxy::CallJavaScriptFunctionOnUIThread( |
- const std::string& function, const base::Value& args) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- |
- std::vector<const base::Value*> args_vector(1, &args); |
- base::string16 update = |
- content::WebUI::GetJavascriptCall(function, args_vector); |
- // Don't forward updates to a destructed UI. |
- if (handler_) |
- handler_->OnUpdate(update); |
-} |