summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-11 23:55:10 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-11 23:55:10 +0000
commita27a938d8511abfaf89d6e2d0e4d4242c76dffed (patch)
tree98b133536459106b96a0ee09e0deb94b8d92c4b3
parent342c2c40bd1729fe985d5a6ee06f6eb28bbcdc22 (diff)
downloadchromium_src-a27a938d8511abfaf89d6e2d0e4d4242c76dffed.zip
chromium_src-a27a938d8511abfaf89d6e2d0e4d4242c76dffed.tar.gz
chromium_src-a27a938d8511abfaf89d6e2d0e4d4242c76dffed.tar.bz2
Refactor plugin process code in the browser process so that the browser/about:memory/task manager/metrics code doesn't depend on PluginProcessHost pointers. In a future changelist I'll add one central child process registry in the browser process.
Review URL: http://codereview.chromium.org/20196 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9621 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/base_lib.scons1
-rw-r--r--base/build/base.vcproj4
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/browser.cc7
-rw-r--r--chrome/browser/browser.scons1
-rw-r--r--chrome/browser/browser.vcproj4
-rw-r--r--chrome/browser/browser_about_handler.cc105
-rw-r--r--chrome/browser/memory_details.cc286
-rw-r--r--chrome/browser/memory_details.h39
-rw-r--r--chrome/browser/metrics/metrics_log.cc13
-rw-r--r--chrome/browser/metrics/metrics_service.cc67
-rw-r--r--chrome/browser/metrics/metrics_service.h36
-rw-r--r--chrome/browser/plugin_process_host.cc110
-rw-r--r--chrome/browser/plugin_process_host.h20
-rw-r--r--chrome/browser/plugin_process_info.h63
-rw-r--r--chrome/browser/plugin_service.cc8
-rw-r--r--chrome/browser/resources/about_memory.html4
-rw-r--r--chrome/browser/task_manager.cc8
-rw-r--r--chrome/browser/task_manager_resource_providers.cc143
-rw-r--r--chrome/browser/task_manager_resource_providers.h51
-rw-r--r--chrome/common/child_process_info.cc51
-rw-r--r--chrome/common/child_process_info.h66
-rw-r--r--chrome/common/common.scons2
-rw-r--r--chrome/common/common.vcproj10
-rw-r--r--chrome/common/notification_type.h46
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h2
27 files changed, 554 insertions, 600 deletions
diff --git a/base/base_lib.scons b/base/base_lib.scons
index ac27c3c..f32ddd8 100644
--- a/base/base_lib.scons
+++ b/base/base_lib.scons
@@ -188,6 +188,7 @@ input_files = ChromeFileList([
'scoped_clipboard_writer.h',
'scoped_comptr_win.h',
'scoped_handle.h',
+ 'scoped_handle_win.h',
'scoped_nsautorelease_pool.h',
'scoped_ptr.h',
'scoped_temp_dir.cc',
diff --git a/base/build/base.vcproj b/base/build/base.vcproj
index feaeae3..b9dacfc 100644
--- a/base/build/base.vcproj
+++ b/base/build/base.vcproj
@@ -718,6 +718,10 @@
>
</File>
<File
+ RelativePath="..\scoped_handle_win.h"
+ >
+ </File>
+ <File
RelativePath="..\scoped_nsautorelease_pool.h"
>
</File>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index a084af4..6a8669d 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -1526,6 +1526,9 @@ each locale. -->
<message name="IDS_TASK_MANAGER_UNKNOWN_PLUGIN_NAME" desc="The prefix for a Task Manager plugin row">
Unknown plug-in
</message>
+ <message name="IDS_TASK_MANAGER_WORKER_PREFIX" desc="The prefix for a Task Manager HTML5 Web Worker process row">
+ Web Worker: <ph name="WORKER_NAME">$1<ex>http://www.domain.com</ex></ph>
+ </message>
<!-- Session Crashed Info Bar-->
<message name="IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON" desc="Title of the restore button in the session crashed view.">
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 95afc30..6491c56 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -96,10 +96,9 @@ class ReducePluginsWorkingSetTask : public Task {
virtual void Run() {
#if defined(OS_WIN)
for (PluginProcessHostIterator iter; !iter.Done(); ++iter) {
- PluginProcessHost* plugin = const_cast<PluginProcessHost*>(*iter);
- DCHECK(plugin->process());
- base::Process process(plugin->process());
- process.ReduceWorkingSet();
+ ChildProcessInfo* child = const_cast<PluginProcessHost*>(*iter);
+ DCHECK(child->process().handle());
+ child->process().ReduceWorkingSet();
}
#endif
}
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index ea092ea..00ac75c 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -118,7 +118,6 @@ input_files = ChromeFileList([
'meta_table_helper.h',
'plugin_process_host.cc',
'plugin_process_host.h',
- 'plugin_process_info.h',
'plugin_service.cc',
'plugin_service.h',
'../tools/build/win/precompiled_wtl.cc',
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 91c6b41..8c02fd3 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -434,10 +434,6 @@
>
</File>
<File
- RelativePath=".\plugin_process_info.h"
- >
- </File>
- <File
RelativePath=".\plugin_service.cc"
>
</File>
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index d8ff07f..bf89af0 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -22,7 +22,6 @@
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
-#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/views/about_ipc_dialog.h"
#include "chrome/common/jstemplate_builder.h"
@@ -93,8 +92,7 @@ class AboutMemoryHandler : public MemoryDetails {
private:
void BindProcessMetrics(DictionaryValue* data,
ProcessMemoryInformation* info);
- void GetTabContentsTitles(RenderProcessHost* rph, ListValue* titles);
- void AppendProcess(ListValue* renderers, ProcessMemoryInformation* info);
+ void AppendProcess(ListValue* child_data, ProcessMemoryInformation* info);
void FinishAboutMemory();
AboutSource* source_;
@@ -496,85 +494,25 @@ void AboutMemoryHandler::BindProcessMetrics(DictionaryValue* data,
data->SetInteger(L"processes", info->num_processes);
}
-// Helper for AboutMemory to iterate over a RenderProcessHost's listeners
-// and retrieve the tab titles.
-void AboutMemoryHandler::GetTabContentsTitles(RenderProcessHost* rph,
- ListValue* titles) {
- RenderProcessHost::listeners_iterator iter;
- // NOTE: This is a bit dangerous. We know that for now, listeners
- // are always RenderWidgetHosts. But in theory, they don't
- // have to be.
- for (iter = rph->listeners_begin(); iter != rph->listeners_end(); iter++) {
- RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second);
- DCHECK(widget);
- if (!widget || !widget->IsRenderView())
- continue;
-
- RenderViewHost* host = static_cast<RenderViewHost*>(widget);
- TabContents* contents = static_cast<WebContents*>(host->delegate());
- DCHECK(contents);
- if (!contents)
- continue;
-
- std::wstring title = contents->GetTitle();
- StringValue* val = NULL;
- if (!title.length())
- title = L"Untitled";
- val = new StringValue(title);
- titles->Append(val);
- }
-}
-
// Helper for AboutMemory to append memory usage information for all
-// sub-processes (renderers & plugins) used by chrome.
-void AboutMemoryHandler::AppendProcess(ListValue* renderers,
+// sub-processes (i.e. renderers, plugins) used by Chrome.
+void AboutMemoryHandler::AppendProcess(ListValue* child_data,
ProcessMemoryInformation* info) {
- DCHECK(renderers && info);
+ DCHECK(child_data && info);
// Append a new DictionaryValue for this renderer to our list.
- DictionaryValue* renderer = new DictionaryValue();
- renderers->Append(renderer);
- BindProcessMetrics(renderer, info);
-
- // Now get more information about the process.
-
- // First, figure out if it is a renderer.
- RenderProcessHost::iterator renderer_iter;
- for (renderer_iter = RenderProcessHost::begin(); renderer_iter !=
- RenderProcessHost::end(); ++renderer_iter) {
- if (renderer_iter->second->process().pid() == info->pid)
- break;
- }
- if (renderer_iter != RenderProcessHost::end()) {
- std::wstring renderer_label(L"Tab ");
- renderer_label.append(FormatNumber(renderer_iter->second->host_id()));
- if (info->is_diagnostics)
- renderer_label.append(L" (diagnostics)");
- renderer->SetString(L"renderer_id", renderer_label);
- ListValue* titles = new ListValue();
- renderer->Set(L"titles", titles);
- GetTabContentsTitles(renderer_iter->second, titles);
- return;
- }
-
- // Figure out if this is a plugin process.
- for (size_t index = 0; index < plugins()->size(); ++index) {
- if (info->pid == (*plugins())[index].pid) {
- // It is a plugin!
- std::wstring label(L"Plug-in");
- std::wstring name;
- renderer->SetString(L"renderer_id", label);
- FileVersionInfo* version_info =
- FileVersionInfo::CreateFileVersionInfo(
- (*plugins())[index].plugin_path);
- if (version_info)
- name = version_info->product_name();
- ListValue* titles = new ListValue();
- renderer->Set(L"titles", titles);
- titles->Append(new StringValue(name));
- return;
- }
- }
+ DictionaryValue* child = new DictionaryValue();
+ child_data->Append(child);
+ BindProcessMetrics(child, info);
+
+ std::wstring child_label(ChildProcessInfo::GetTypeNameInEnglish(info->type));
+ if (info->is_diagnostics)
+ child_label.append(L" (diagnostics)");
+ child->SetString(L"child_name", child_label);
+ ListValue* titles = new ListValue();
+ child->Set(L"titles", titles);
+ for (size_t i = 0; i < info->titles.size(); ++i)
+ titles->Append(new StringValue(info->titles[i]));
}
@@ -631,20 +569,18 @@ void AboutMemoryHandler::OnDetailsAvailable() {
if (log_string.length() > 0)
LOG(INFO) << "memory: " << log_string;
-
// Set the browser & renderer detailed process data.
DictionaryValue* browser_data = new DictionaryValue();
root.Set(L"browzr_data", browser_data);
- ListValue* renderer_data = new ListValue();
- root.Set(L"renderer_data", renderer_data);
+ ListValue* child_data = new ListValue();
+ root.Set(L"child_data", child_data);
- DWORD browser_pid = GetCurrentProcessId();
ProcessData process = browser_processes[0]; // Chrome is the first browser.
for (size_t index = 0; index < process.processes.size(); index++) {
- if (process.processes[index].pid == browser_pid)
+ if (process.processes[index].type == ChildProcessInfo::BROWSER_PROCESS)
BindProcessMetrics(browser_data, &process.processes[index]);
else
- AppendProcess(renderer_data, &process.processes[index]);
+ AppendProcess(child_data, &process.processes[index]);
}
// Get about_memory.html
@@ -665,4 +601,3 @@ void BrowserAboutHandler::AboutMemory(AboutSource* source, int request_id) {
// The AboutMemoryHandler cleans itself up.
new AboutMemoryHandler(source, request_id);
}
-
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index f2c3f79..e1279fe 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -10,9 +10,9 @@
#include "base/image_util.h"
#include "base/message_loop.h"
#include "base/process_util.h"
+#include "base/scoped_ptr.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_trial.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/plugin_process_host.h"
#include "chrome/browser/plugin_service.h"
@@ -64,155 +64,190 @@ void MemoryDetails::StartFetch() {
// In order to process this request, we need to use the plugin information.
// However, plugin process information is only available from the IO thread.
g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &MemoryDetails::CollectPluginInformation));
+ NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnIOThread));
}
-void MemoryDetails::CollectPluginInformation() {
+void MemoryDetails::CollectChildInfoOnIOThread() {
DCHECK(MessageLoop::current() ==
ChromeThread::GetMessageLoop(ChromeThread::IO));
+ std::vector<ProcessMemoryInformation> child_info;
+
// Collect the list of plugins.
for (PluginProcessHostIterator plugin_iter;
!plugin_iter.Done(); ++plugin_iter) {
- PluginProcessHost* plugin = const_cast<PluginProcessHost*>(*plugin_iter);
- DCHECK(plugin);
- if (!plugin || !plugin->process())
+ ChildProcessInfo* child = const_cast<PluginProcessHost*>(*plugin_iter);
+ DCHECK(child);
+ if (!child || !child->process().handle())
continue;
- PluginProcessInformation info;
- info.pid = base::GetProcId(plugin->process());
- if (info.pid != 0) {
- info.plugin_path = plugin->plugin_path();
- plugins_.push_back(info);
- }
+ ProcessMemoryInformation info;
+ info.pid = child->process().pid();
+ if (!info.pid)
+ continue;
+
+ info.type = child->type();
+ info.titles.push_back(child->name());
+ child_info.push_back(info);
}
// Now go do expensive memory lookups from the file thread.
ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE,
- NewRunnableMethod(this, &MemoryDetails::CollectProcessData));
+ NewRunnableMethod(this, &MemoryDetails::CollectProcessData, child_info));
}
-void MemoryDetails::CollectProcessData() {
+void MemoryDetails::CollectProcessData(
+ std::vector<ProcessMemoryInformation> child_info) {
DCHECK(MessageLoop::current() ==
ChromeThread::GetMessageLoop(ChromeThread::FILE));
int array_size = 32;
- DWORD* process_list = NULL;
+ scoped_ptr_malloc<DWORD> process_list;
DWORD bytes_used = 0;
do {
array_size *= 2;
- process_list = static_cast<DWORD*>(
- realloc(process_list, sizeof(*process_list) * array_size));
+ process_list.reset(static_cast<DWORD*>(
+ realloc(process_list.release(), sizeof(DWORD) * array_size)));
// EnumProcesses doesn't return an error if the array is too small.
// We have to check if the return buffer is full, and if so, call it
// again. See msdn docs for more info.
- if (!EnumProcesses(process_list, array_size * sizeof(*process_list),
+ if (!EnumProcesses(process_list.get(), array_size * sizeof(DWORD),
&bytes_used)) {
LOG(ERROR) << "EnumProcesses failed: " << GetLastError();
return;
}
- } while (bytes_used == (array_size * sizeof(*process_list)));
+ } while (bytes_used == (array_size * sizeof(DWORD)));
- int num_processes = bytes_used / sizeof(*process_list);
+ int num_processes = bytes_used / sizeof(DWORD);
// Clear old data.
for (int index = 0; index < arraysize(g_process_template); index++)
process_data_[index].processes.clear();
for (int index = 0; index < num_processes; index++) {
- HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, process_list[index]);
- if (handle) {
- TCHAR name[MAX_PATH];
- if (GetModuleBaseName(handle, NULL, name, MAX_PATH-1)) {
- for (int index2 = 0; index2 < arraysize(g_process_template); index2++) {
- if (_wcsicmp(process_data_[index2].process_name, name) == 0) {
- // Get Memory Information.
- ProcessMemoryInformation info;
- info.pid = process_list[index];
- scoped_ptr<base::ProcessMetrics> metrics;
- metrics.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
- metrics->GetCommittedKBytes(&info.committed);
- metrics->GetWorkingSetKBytes(&info.working_set);
-
- // Get Version Information.
- if (index2 == 0) { // Chrome
- scoped_ptr<FileVersionInfo> version_info(
- FileVersionInfo::CreateFileVersionInfoForCurrentModule());
- if (version_info != NULL)
- info.version = version_info->file_version();
- } else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH-1)) {
- std::wstring str_name(name);
- scoped_ptr<FileVersionInfo> version_info(
- FileVersionInfo::CreateFileVersionInfo(str_name));
- if (version_info != NULL) {
- info.version = version_info->product_version();
- info.product_name = version_info->product_name();
- }
- }
-
- // Add the process info to our list.
- process_data_[index2].processes.push_back(info);
- break;
- }
+ int pid = process_list.get()[index];
+ ScopedHandle handle(OpenProcess(
+ PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
+ if (!handle.Get())
+ continue;
+ TCHAR name[MAX_PATH];
+ if (!GetModuleBaseName(handle, NULL, name, MAX_PATH - 1))
+ continue;
+ for (int index2 = 0; index2 < arraysize(g_process_template); index2++) {
+ if (_wcsicmp(process_data_[index2].process_name, name) != 0)
+ continue;
+ // Get Memory Information.
+ ProcessMemoryInformation info;
+ info.pid = pid;
+ if (info.pid == GetCurrentProcessId())
+ info.type = ChildProcessInfo::BROWSER_PROCESS;
+ else
+ info.type = ChildProcessInfo::UNKNOWN_PROCESS;
+
+ scoped_ptr<base::ProcessMetrics> metrics;
+ metrics.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
+ metrics->GetCommittedKBytes(&info.committed);
+ metrics->GetWorkingSetKBytes(&info.working_set);
+
+ // Get Version Information.
+ if (index2 == 0) { // Chrome
+ scoped_ptr<FileVersionInfo> version_info(
+ FileVersionInfo::CreateFileVersionInfoForCurrentModule());
+ if (version_info != NULL)
+ info.version = version_info->file_version();
+ // Check if this is one of the child processes whose data we collected
+ // on the IO thread, and if so copy over that data.
+ for (size_t child = 0; child < child_info.size(); child++) {
+ if (child_info[child].pid != info.pid)
+ continue;
+ info.titles = child_info[child].titles;
+ info.type = child_info[child].type;
+ break;
+ }
+ } else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH - 1)) {
+ std::wstring str_name(name);
+ scoped_ptr<FileVersionInfo> version_info(
+ FileVersionInfo::CreateFileVersionInfo(str_name));
+ if (version_info != NULL) {
+ info.version = version_info->product_version();
+ info.product_name = version_info->product_name();
}
}
- CloseHandle(handle);
+
+ // Add the process info to our list.
+ process_data_[index2].processes.push_back(info);
+ break;
}
}
- free(process_list);
// Finally return to the browser thread.
ui_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &MemoryDetails::CollectRenderHostInformation));
+ NewRunnableMethod(this, &MemoryDetails::CollectChildInfoOnUIThread));
}
-void MemoryDetails::CollectRenderHostInformation() {
+void MemoryDetails::CollectChildInfoOnUIThread() {
DCHECK(MessageLoop::current() == ui_loop_);
- // Determine if this is a diagnostics-related process. We skip all
- // diagnostics pages (e.g. "about:xxx" URLs). Iterate the RenderProcessHosts
- // to find the tab contents. If it is of type TAB_CONTENTS_ABOUT_UI, mark
- // the process as diagnostics related.
+ // Get more information about the process.
for (size_t index = 0; index < process_data_[CHROME_BROWSER].processes.size();
index++) {
+ // Check if it's a renderer, if so get the list of page titles in it and
+ // check if it's a diagnostics-related process. We skip all diagnostics
+ // pages (e.g. "about:xxx" URLs). Iterate the RenderProcessHosts to find
+ // the tab contents. If it is of type TAB_CONTENTS_ABOUT_UI, mark the
+ // process as diagnostics related.
RenderProcessHost::iterator renderer_iter;
for (renderer_iter = RenderProcessHost::begin(); renderer_iter !=
RenderProcessHost::end(); ++renderer_iter) {
DCHECK(renderer_iter->second);
- if (process_data_[CHROME_BROWSER].processes[index].pid ==
- renderer_iter->second->process().pid()) {
- // The RenderProcessHost may host multiple TabContents. Any
- // of them which contain diagnostics information make the whole
- // process be considered a diagnostics process.
- //
- // NOTE: This is a bit dangerous. We know that for now, listeners
- // are always RenderWidgetHosts. But in theory, they don't
- // have to be.
- RenderProcessHost::listeners_iterator iter;
- for (iter = renderer_iter->second->listeners_begin();
- iter != renderer_iter->second->listeners_end(); ++iter) {
- RenderWidgetHost* widget =
- static_cast<RenderWidgetHost*>(iter->second);
- DCHECK(widget);
- if (!widget || !widget->IsRenderView())
- continue;
-
- RenderViewHost* host = static_cast<RenderViewHost*>(widget);
- TabContents* contents =
- static_cast<WebContents*>(host->delegate());
- DCHECK(contents);
- if (!contents)
- continue;
-
- if (contents->type() == TAB_CONTENTS_ABOUT_UI)
- process_data_[CHROME_BROWSER].processes[index].is_diagnostics =
- true;
- }
+ ProcessMemoryInformation& process =
+ process_data_[CHROME_BROWSER].processes[index];
+ if (process.pid != renderer_iter->second->process().pid())
+ continue;
+ process.type = ChildProcessInfo::RENDER_PROCESS;
+ // The RenderProcessHost may host multiple TabContents. Any
+ // of them which contain diagnostics information make the whole
+ // process be considered a diagnostics process.
+ //
+ // NOTE: This is a bit dangerous. We know that for now, listeners
+ // are always RenderWidgetHosts. But in theory, they don't
+ // have to be.
+ RenderProcessHost::listeners_iterator iter;
+ for (iter = renderer_iter->second->listeners_begin();
+ iter != renderer_iter->second->listeners_end(); ++iter) {
+ RenderWidgetHost* widget =
+ static_cast<RenderWidgetHost*>(iter->second);
+ DCHECK(widget);
+ if (!widget || !widget->IsRenderView())
+ continue;
+
+ RenderViewHost* host = static_cast<RenderViewHost*>(widget);
+ TabContents* contents =
+ static_cast<WebContents*>(host->delegate());
+ DCHECK(contents);
+ if (!contents)
+ continue;
+ std::wstring title = contents->GetTitle();
+ if (!title.length())
+ title = L"Untitled";
+ process.titles.push_back(title);
+ if (contents->type() == TAB_CONTENTS_ABOUT_UI)
+ process.is_diagnostics = true;
}
}
}
+ // Get rid of other Chrome processes that are from a different profile.
+ for (size_t index = 0; index < process_data_[CHROME_BROWSER].processes.size();
+ index++) {
+ if (process_data_[CHROME_BROWSER].processes[index].type ==
+ ChildProcessInfo::UNKNOWN_PROCESS) {
+ process_data_[CHROME_BROWSER].processes.erase(
+ process_data_[CHROME_BROWSER].processes.begin() + index);
+ index --;
+ }
+ }
+
UpdateHistograms();
OnDetailsAvailable();
@@ -222,61 +257,36 @@ void MemoryDetails::UpdateHistograms() {
// Reports a set of memory metrics to UMA.
// Memory is measured in units of 10KB.
- // If field trial is active, report results in special histograms.
- static scoped_refptr<FieldTrial> trial(
- FieldTrialList::Find(BrowserTrial::kMemoryModelFieldTrial));
-
- DWORD browser_pid = GetCurrentProcessId();
ProcessData browser = process_data_[CHROME_BROWSER];
size_t aggregate_memory = 0;
+ int plugin_count = 0;
+ int worker_count = 0;
for (size_t index = 0; index < browser.processes.size(); index++) {
int sample = static_cast<int>(browser.processes[index].working_set.priv);
aggregate_memory += sample;
- if (browser.processes[index].pid == browser_pid) {
- if (trial.get()) {
- if (trial->boolean_value())
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Browser_trial_high_memory", sample);
- else
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Browser_trial_med_memory", sample);
- } else {
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Browser", sample);
- }
- } else {
- bool is_plugin_process = false;
- for (size_t index2 = 0; index2 < plugins_.size(); index2++) {
- if (browser.processes[index].pid == plugins_[index2].pid) {
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Plugin", sample);
- is_plugin_process = true;
- break;
- }
- }
- if (!is_plugin_process) {
- if (trial.get()) {
- if (trial->boolean_value())
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Renderer_trial_high_memory",
- sample);
- else
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Renderer_trial_med_memory",
- sample);
- } else {
- UMA_HISTOGRAM_MEMORY_KB(L"Memory.Renderer", sample);
- }
- }
+ switch (browser.processes[index].type) {
+ case ChildProcessInfo::BROWSER_PROCESS:
+ UMA_HISTOGRAM_MEMORY_KB(L"Memory.Browser", sample);
+ break;
+ case ChildProcessInfo::RENDER_PROCESS:
+ UMA_HISTOGRAM_MEMORY_KB(L"Memory.Renderer", sample);
+ break;
+ case ChildProcessInfo::PLUGIN_PROCESS:
+ UMA_HISTOGRAM_MEMORY_KB(L"Memory.Plugin", sample);
+ plugin_count++;
+ break;
+ case ChildProcessInfo::WORKER_PROCESS:
+ UMA_HISTOGRAM_MEMORY_KB(L"Memory.Worker", sample);
+ worker_count++;
+ break;
}
}
+
UMA_HISTOGRAM_COUNTS_100(L"Memory.ProcessCount",
static_cast<int>(browser.processes.size()));
- UMA_HISTOGRAM_COUNTS_100(L"Memory.PluginProcessCount",
- static_cast<int>(plugins_.size()));
+ UMA_HISTOGRAM_COUNTS_100(L"Memory.PluginProcessCount", plugin_count);
+ UMA_HISTOGRAM_COUNTS_100(L"Memory.WorkerProcessCount", worker_count);
int total_sample = static_cast<int>(aggregate_memory / 1000);
- if (trial.get()) {
- if (trial->boolean_value())
- UMA_HISTOGRAM_MEMORY_MB(L"Memory.Total_trial_high_memory", total_sample);
- else
- UMA_HISTOGRAM_MEMORY_MB(L"Memory.Total_trial_med_memory", total_sample);
- } else {
- UMA_HISTOGRAM_MEMORY_MB(L"Memory.Total", total_sample);
- }
+ UMA_HISTOGRAM_MEMORY_MB(L"Memory.Total", total_sample);
}
-
diff --git a/chrome/browser/memory_details.h b/chrome/browser/memory_details.h
index 0a542cc..17a00a1 100644
--- a/chrome/browser/memory_details.h
+++ b/chrome/browser/memory_details.h
@@ -12,6 +12,7 @@
#include "base/file_path.h"
#include "base/process_util.h"
#include "base/ref_counted.h"
+#include "chrome/common/child_process_info.h"
class MessageLoop;
@@ -38,17 +39,14 @@ struct ProcessMemoryInformation {
// A process is a diagnostics process if it is rendering
// about:xxx information.
bool is_diagnostics;
+ // If this is a child process of Chrome, what type (i.e. plugin) it is.
+ ChildProcessInfo::ProcessType type;
+ // A collection of titles used, i.e. for a tab it'll show all the page titles.
+ std::vector<std::wstring> titles;
};
typedef std::vector<ProcessMemoryInformation> ProcessMemoryInformationList;
-// Information that we need about a plugin process.
-struct PluginProcessInformation {
- int pid;
- FilePath plugin_path;
-};
-typedef std::vector<PluginProcessInformation> PluginProcessInformationList;
-
// Browser Process Information.
struct ProcessData {
const wchar_t* name;
@@ -95,9 +93,6 @@ class MemoryDetails : public base::RefCountedThreadSafe<MemoryDetails> {
// after OnDetailsAvailable() has been called.
ProcessData* processes() { return process_data_; }
- // Access to the plugin details.
- const PluginProcessInformationList* plugins() const { return &plugins_; }
-
// Initiate updating the current memory details. These are fetched
// asynchronously because data must be collected from multiple threads.
// OnDetailsAvailable will be called when this process is complete.
@@ -106,30 +101,30 @@ class MemoryDetails : public base::RefCountedThreadSafe<MemoryDetails> {
virtual void OnDetailsAvailable() {}
private:
- // Collect the a list of information about current plugin processes that
- // will be used by about:memory. When finished, invokes back to the
- // return_loop to run the rest of the about:memory functionality.
- // Runs on the IO thread because the PluginProcessHost is only accessible
- // from the IO thread.
- void CollectPluginInformation();
+ // Collect child process information on the IO thread. This is needed because
+ // information about some child process types (i.e. plugins) can only be taken
+ // on that thread. The data will be used by about:memory. When finished,
+ // invokes back to the file thread to run the rest of the about:memory
+ // functionality.
+ void CollectChildInfoOnIOThread();
// Collect current process information from the OS and store it
// for processing. If data has already been collected, clears old
// data and re-collects the data.
// Note - this function enumerates memory details from many processes
- // and is fairly expensive to run.
- void CollectProcessData();
+ // and is fairly expensive to run, hence it's run on the file thread.
+ // The parameter holds information about processes from the IO thread.
+ void CollectProcessData(std::vector<ProcessMemoryInformation>);
- // Collect renderer specific information. This information is gathered
- // on the Browser thread, where the RenderHostIterator is accessible.
- void CollectRenderHostInformation();
+ // Collect child process information on the UI thread. Information about
+ // renderer processes is only available there.
+ void CollectChildInfoOnUIThread();
// Each time we take a memory sample, we do a little work to update
// the global histograms for tracking memory usage.
void UpdateHistograms();
ProcessData process_data_[MAX_BROWSERS];
- PluginProcessInformationList plugins_;
MessageLoop* ui_loop_;
DISALLOW_EVIL_CONSTRUCTORS(MemoryDetails);
diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc
index 3603e0c..27cb88e 100644
--- a/chrome/browser/metrics/metrics_log.cc
+++ b/chrome/browser/metrics/metrics_log.cc
@@ -382,16 +382,13 @@ void MetricsLog::WritePluginStabilityElements(PrefService* pref) {
}
DictionaryValue* plugin_dict = static_cast<DictionaryValue*>(*iter);
- std::wstring plugin_path;
- plugin_dict->GetString(prefs::kStabilityPluginPath, &plugin_path);
- plugin_path = file_util::GetFilenameFromPath(plugin_path);
- if (plugin_path.empty()) {
- NOTREACHED();
- continue;
- }
+ std::wstring plugin_name;
+ plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
OPEN_ELEMENT_FOR_SCOPE("pluginstability");
- WriteAttribute("filename", CreateBase64Hash(WideToUTF8(plugin_path)));
+ // Use "filename" instead of "name", otherwise we need to update the
+ // UMA servers.
+ WriteAttribute("filename", CreateBase64Hash(WideToUTF8(plugin_name)));
int launches = 0;
plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches);
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index b25b5b1..55aca76 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -170,12 +170,12 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/load_notification_details.h"
#include "chrome/browser/memory_details.h"
-#include "chrome/browser/plugin_process_info.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
+#include "chrome/common/child_process_info.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/libxml_utils.h"
#include "chrome/common/notification_service.h"
@@ -464,10 +464,10 @@ void MetricsService::Observe(NotificationType type,
LogRendererInSandbox(*Details<bool>(details).ptr());
break;
- case NotificationType::PLUGIN_PROCESS_HOST_CONNECTED:
- case NotificationType::PLUGIN_PROCESS_CRASHED:
- case NotificationType::PLUGIN_INSTANCE_CREATED:
- LogPluginChange(type, source, details);
+ case NotificationType::CHILD_PROCESS_HOST_CONNECTED:
+ case NotificationType::CHILD_PROCESS_CRASHED:
+ case NotificationType::CHILD_INSTANCE_CREATED:
+ LogChildProcessChange(type, source, details);
break;
case NotificationType::TEMPLATE_URL_MODEL_LOADED:
@@ -723,11 +723,11 @@ void MetricsService::ListenerRegistration(bool start_listening) {
start_listening);
AddOrRemoveObserver(this, NotificationType::RENDERER_PROCESS_HANG,
start_listening);
- AddOrRemoveObserver(this, NotificationType::PLUGIN_PROCESS_HOST_CONNECTED,
+ AddOrRemoveObserver(this, NotificationType::CHILD_PROCESS_HOST_CONNECTED,
start_listening);
- AddOrRemoveObserver(this, NotificationType::PLUGIN_INSTANCE_CREATED,
+ AddOrRemoveObserver(this, NotificationType::CHILD_INSTANCE_CREATED,
start_listening);
- AddOrRemoveObserver(this, NotificationType::PLUGIN_PROCESS_CRASHED,
+ AddOrRemoveObserver(this, NotificationType::CHILD_PROCESS_CRASHED,
start_listening);
AddOrRemoveObserver(this, NotificationType::TEMPLATE_URL_MODEL_LOADED,
start_listening);
@@ -1533,26 +1533,29 @@ void MetricsService::LogRendererHang() {
IncrementPrefValue(prefs::kStabilityRendererHangCount);
}
-void MetricsService::LogPluginChange(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- FilePath plugin = Details<PluginProcessInfo>(details)->plugin_path();
+void MetricsService::LogChildProcessChange(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ const std::wstring& child_name =
+ Details<ChildProcessInfo>(details)->name();
- if (plugin_stats_buffer_.find(plugin) == plugin_stats_buffer_.end()) {
- plugin_stats_buffer_[plugin] = PluginStats();
+ if (child_process_stats_buffer_.find(child_name) ==
+ child_process_stats_buffer_.end()) {
+ child_process_stats_buffer_[child_name] = ChildProcessStats();
}
- PluginStats& stats = plugin_stats_buffer_[plugin];
+ ChildProcessStats& stats = child_process_stats_buffer_[child_name];
switch (type.value) {
- case NotificationType::PLUGIN_PROCESS_HOST_CONNECTED:
+ case NotificationType::CHILD_PROCESS_HOST_CONNECTED:
stats.process_launches++;
break;
- case NotificationType::PLUGIN_INSTANCE_CREATED:
+ case NotificationType::CHILD_INSTANCE_CREATED:
stats.instances++;
break;
- case NotificationType::PLUGIN_PROCESS_CRASHED:
+ case NotificationType::CHILD_PROCESS_CRASHED:
stats.process_crashes++;
break;
@@ -1620,18 +1623,18 @@ void MetricsService::RecordPluginChanges(PrefService* pref) {
}
DictionaryValue* plugin_dict = static_cast<DictionaryValue*>(*value_iter);
- FilePath::StringType plugin_path_str;
- plugin_dict->GetString(prefs::kStabilityPluginPath, &plugin_path_str);
- if (plugin_path_str.empty()) {
+ std::wstring plugin_name;
+ plugin_dict->GetString(prefs::kStabilityPluginName, &plugin_name);
+ if (plugin_name.empty()) {
NOTREACHED();
continue;
}
- FilePath plugin_path(plugin_path_str);
- if (plugin_stats_buffer_.find(plugin_path) == plugin_stats_buffer_.end())
+ if (child_process_stats_buffer_.find(plugin_name) ==
+ child_process_stats_buffer_.end())
continue;
- PluginStats stats = plugin_stats_buffer_[plugin_path];
+ ChildProcessStats stats = child_process_stats_buffer_[plugin_name];
if (stats.process_launches) {
int launches = 0;
plugin_dict->GetInteger(prefs::kStabilityPluginLaunches, &launches);
@@ -1651,19 +1654,19 @@ void MetricsService::RecordPluginChanges(PrefService* pref) {
plugin_dict->SetInteger(prefs::kStabilityPluginInstances, instances);
}
- plugin_stats_buffer_.erase(plugin_path);
+ child_process_stats_buffer_.erase(plugin_name);
}
// Now go through and add dictionaries for plugins that didn't already have
// reports in Local State.
- for (std::map<FilePath, PluginStats>::iterator cache_iter =
- plugin_stats_buffer_.begin();
- cache_iter != plugin_stats_buffer_.end(); ++cache_iter) {
- FilePath plugin_path = cache_iter->first;
- PluginStats stats = cache_iter->second;
+ for (std::map<std::wstring, ChildProcessStats>::iterator cache_iter =
+ child_process_stats_buffer_.begin();
+ cache_iter != child_process_stats_buffer_.end(); ++cache_iter) {
+ std::wstring plugin_name = cache_iter->first;
+ ChildProcessStats stats = cache_iter->second;
DictionaryValue* plugin_dict = new DictionaryValue;
- plugin_dict->SetString(prefs::kStabilityPluginPath, plugin_path.value());
+ plugin_dict->SetString(prefs::kStabilityPluginName, plugin_name);
plugin_dict->SetInteger(prefs::kStabilityPluginLaunches,
stats.process_launches);
plugin_dict->SetInteger(prefs::kStabilityPluginCrashes,
@@ -1672,7 +1675,7 @@ void MetricsService::RecordPluginChanges(PrefService* pref) {
stats.instances);
plugins->Append(plugin_dict);
}
- plugin_stats_buffer_.clear();
+ child_process_stats_buffer_.clear();
}
bool MetricsService::CanLogNotification(NotificationType type,
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index 64780d7..d42d953 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -15,7 +15,6 @@
#include <vector>
#include "base/basictypes.h"
-#include "base/file_path.h"
#include "base/histogram.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
@@ -30,22 +29,23 @@ class PrefService;
class Profile;
class TemplateURLModel;
-// This is used to quickly log stats from plugin-related notifications in
-// MetricsService::plugin_stats_buffer_. The buffer's contents are transferred
+// This is used to quickly log stats from child process related notifications in
+// MetricsService::child_stats_buffer_. The buffer's contents are transferred
// out when Local State is periodically saved. The information is then
// reported to the UMA server on next launch.
-struct PluginStats {
+struct ChildProcessStats {
public:
- PluginStats() : process_launches(0), process_crashes(0), instances(0) {}
+ ChildProcessStats() : process_launches(0), process_crashes(0), instances(0) {}
- // The number of times that the given plugin process has been launched
+ // The number of times that the given child process has been launched
int process_launches;
- // The number of times that the given plugin process has crashed
+ // The number of times that the given child process has crashed
int process_crashes;
- // The number of instances of this plugin that have been created.
- // An instance is a DOM object rendered by this plugin during a page load.
+ // The number of instances of this child process that have been created.
+ // An instance is a DOM object rendered by this child process during a page
+ // load.
int instances;
};
@@ -315,12 +315,12 @@ class MetricsService : public NotificationObserver,
// Sets preferences for the for the number of bookmarks in model.
void LogBookmarks(BookmarkModel* model);
- // Records a plugin-related notification. These are recorded to an in-object
- // buffer because these notifications are sent on page load, and we don't
- // want to slow that down.
- void LogPluginChange(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
+ // Records a child process related notification. These are recorded to an
+ // in-object buffer because these notifications are sent on page load, and we
+ // don't want to slow that down.
+ void LogChildProcessChange(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
// Logs keywords specific metrics. Keyword metrics are recorded in the
// profile specific metrics.
@@ -421,9 +421,9 @@ class MetricsService : public NotificationObserver,
WindowMap window_map_;
int next_window_id_;
- // Buffer of plugin notifications for quick access. See PluginStats
- // documentation above for more details.
- std::map<FilePath, PluginStats> plugin_stats_buffer_;
+ // Buffer of child process notifications for quick access. See
+ // ChildProcessStats documentation above for more details.
+ std::map<std::wstring, ChildProcessStats> child_process_stats_buffer_;
ScopedRunnableMethodFactory<MetricsService> log_sender_factory_;
ScopedRunnableMethodFactory<MetricsService> state_saver_factory_;
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index feab679..6ba74de 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -10,15 +10,16 @@
#include "base/command_line.h"
#include "base/debug_util.h"
#include "base/file_util.h"
+#include "base/file_version_info.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process_util.h"
+#include "base/scoped_ptr.h"
#include "base/thread.h"
#include "base/win_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_plugin_browsing_context.h"
#include "chrome/browser/chrome_thread.h"
-#include "chrome/browser/plugin_process_info.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
@@ -32,6 +33,7 @@
#include "chrome/common/ipc_logging.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/process_watcher.h"
#include "chrome/common/render_messages.h"
@@ -51,47 +53,20 @@ static const char kDefaultPluginFinderURL[] =
class PluginNotificationTask : public Task {
public:
PluginNotificationTask(NotificationType notification_type,
- FilePath plugin_path,
- HANDLE process);
+ ChildProcessInfo* info)
+ : notification_type_(notification_type), info_(*info) { }
- virtual void Run();
+ virtual void Run() {
+ NotificationService::current()->
+ Notify(notification_type_, NotificationService::AllSources(),
+ Details<ChildProcessInfo>(&info_));
+ }
private:
NotificationType notification_type_;
- FilePath plugin_path_;
- HANDLE process_;
+ ChildProcessInfo info_;
};
-PluginNotificationTask::PluginNotificationTask(
- NotificationType notification_type,
- FilePath plugin_path,
- HANDLE process)
- : notification_type_(notification_type),
- process_(process),
- plugin_path_(plugin_path) {
-}
-
-void PluginNotificationTask::Run() {
- // Verify that the notification type is one that makes sense.
- switch (notification_type_.value) {
- case NotificationType::PLUGIN_PROCESS_HOST_CONNECTED:
- case NotificationType::PLUGIN_PROCESS_HOST_DISCONNECTED:
- case NotificationType::PLUGIN_PROCESS_CRASHED:
- case NotificationType::PLUGIN_INSTANCE_CREATED:
- break;
-
- default:
- NOTREACHED();
- return;
- }
-
- PluginProcessInfo ppi(plugin_path_, process_);
- // As mentioned in the notification_types.h, the PluginProcessInfo details
- // are only valid for the time of the notification.
- NotificationService::current()->
- Notify(notification_type_, NotificationService::AllSources(),
- Details<PluginProcessInfo>(&ppi));
-}
// The PluginDownloadUrlHelper is used to handle one download URL request
// from the plugin. Each download request is handled by a new instance
@@ -383,27 +358,29 @@ class DestroyWindowTask : public Task {
PluginProcessHost::PluginProcessHost(PluginService* plugin_service)
- : process_(NULL),
- opening_channel_(false),
+ : opening_channel_(false),
resource_dispatcher_host_(plugin_service->resource_dispatcher_host()),
ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)),
plugin_service_(plugin_service) {
DCHECK(resource_dispatcher_host_);
+ set_type(PLUGIN_PROCESS);
}
PluginProcessHost::~PluginProcessHost() {
- if (process_.handle()) {
+ if (process().handle()) {
watcher_.StopWatching();
- ProcessWatcher::EnsureProcessTerminated(process_.handle());
+ ProcessWatcher::EnsureProcessTerminated(process().handle());
}
}
-bool PluginProcessHost::Init(const FilePath& plugin_path,
+bool PluginProcessHost::Init(const WebPluginInfo& info,
const std::string& activex_clsid,
const std::wstring& locale) {
DCHECK(channel_.get() == NULL);
- plugin_path_ = plugin_path;
+ info_ = info;
+ set_name(info_.name);
+
channel_id_ = GenerateRandomChannelID(this);
channel_.reset(new IPC::Channel(channel_id_,
IPC::Channel::MODE_SERVER,
@@ -480,7 +457,7 @@ bool PluginProcessHost::Init(const FilePath& plugin_path,
channel_id_);
cmd_line.AppendSwitchWithValue(switches::kPluginPath,
- plugin_path.ToWStringHack());
+ info.path.ToWStringHack());
bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox) &&
browser_command_line.HasSwitch(switches::kSafePlugins);
@@ -499,7 +476,7 @@ bool PluginProcessHost::Init(const FilePath& plugin_path,
std::wstring trusted_plugins =
browser_command_line.GetSwitchValue(switches::kTrustedPlugins);
- if (!AddPolicyForPlugin(plugin_path, activex_clsid, trusted_plugins,
+ if (!AddPolicyForPlugin(info.path, activex_clsid, trusted_plugins,
policy)) {
NOTREACHED();
return false;
@@ -520,7 +497,7 @@ bool PluginProcessHost::Init(const FilePath& plugin_path,
ResumeThread(target.hThread);
CloseHandle(target.hThread);
- process_.set_handle(target.hProcess);
+ process().set_handle(target.hProcess);
// Help the process a little. It can't start the debugger by itself if
// the process is in a sandbox.
@@ -528,23 +505,23 @@ bool PluginProcessHost::Init(const FilePath& plugin_path,
DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId);
} else {
// spawn child process
- HANDLE process;
- if (!base::LaunchApp(cmd_line, false, false, &process))
+ HANDLE handle;
+ if (!base::LaunchApp(cmd_line, false, false, &handle))
return false;
- process_.set_handle(process);
+ process().set_handle(handle);
}
- watcher_.StartWatching(process_.handle(), this);
+ watcher_.StartWatching(process().handle(), this);
FilePath gears_path;
if (PathService::Get(chrome::FILE_GEARS_PLUGIN, &gears_path)) {
FilePath::StringType gears_path_lc = StringToLowerASCII(gears_path.value());
FilePath::StringType plugin_path_lc =
- StringToLowerASCII(plugin_path.value());
+ StringToLowerASCII(info.path.value());
if (plugin_path_lc == gears_path_lc) {
// Give Gears plugins "background" priority. See
// http://b/issue?id=1280317.
- process_.SetProcessBackgrounded(true);
+ process().SetProcessBackgrounded(true);
}
}
@@ -563,22 +540,21 @@ bool PluginProcessHost::Send(IPC::Message* msg) {
// indicates the plugin process has exited
void PluginProcessHost::OnObjectSignaled(HANDLE object) {
- DCHECK(process_.handle());
- DCHECK_EQ(object, process_.handle());
+ DCHECK(process().handle());
+ DCHECK_EQ(object, process().handle());
bool did_crash = base::DidProcessCrash(object);
if (did_crash) {
// Report that this plugin crashed.
plugin_service_->main_message_loop()->PostTask(FROM_HERE,
- new PluginNotificationTask(NotificationType::PLUGIN_PROCESS_CRASHED,
- plugin_path(), object));
+ new PluginNotificationTask(
+ NotificationType::CHILD_PROCESS_CRASHED, this));
}
// Notify in the main loop of the disconnection.
plugin_service_->main_message_loop()->PostTask(FROM_HERE,
new PluginNotificationTask(
- NotificationType::PLUGIN_PROCESS_HOST_DISCONNECTED,
- plugin_path(), object));
+ NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, this));
// Cancel all requests for plugin processes.
// TODO(mpcomplete): use a real process ID when http://b/issue?id=1210062 is
@@ -647,8 +623,7 @@ void PluginProcessHost::OnChannelConnected(int32 peer_pid) {
// Notify in the main loop of the connection.
plugin_service_->main_message_loop()->PostTask(FROM_HERE,
new PluginNotificationTask(
- NotificationType::PLUGIN_PROCESS_HOST_CONNECTED,
- plugin_path(), process()));
+ NotificationType::CHILD_PROCESS_HOST_CONNECTED, this));
}
void PluginProcessHost::OnChannelError() {
@@ -669,8 +644,8 @@ void PluginProcessHost::OpenChannelToPlugin(
IPC::Message* reply_msg) {
// Notify in the main loop of the instantiation.
plugin_service_->main_message_loop()->PostTask(FROM_HERE,
- new PluginNotificationTask(NotificationType::PLUGIN_INSTANCE_CREATED,
- plugin_path(), process()));
+ new PluginNotificationTask(
+ NotificationType::CHILD_INSTANCE_CREATED, this));
if (opening_channel_) {
pending_requests_.push_back(
@@ -704,7 +679,7 @@ void PluginProcessHost::OnRequestResource(
context = Profile::GetDefaultRequestContext();
resource_dispatcher_host_->BeginRequest(this,
- process_.handle(),
+ process().handle(),
render_process_host_id,
MSG_ROUTING_CONTROL,
request_id,
@@ -743,7 +718,7 @@ void PluginProcessHost::OnSyncLoad(
context = Profile::GetDefaultRequestContext();
resource_dispatcher_host_->BeginRequest(this,
- process_.handle(),
+ process().handle(),
render_process_host_id,
MSG_ROUTING_CONTROL,
request_id,
@@ -802,7 +777,7 @@ void PluginProcessHost::RequestPluginChannel(
HANDLE renderer_handle = NULL;
BOOL result = DuplicateHandle(GetCurrentProcess(),
renderer_message_filter->renderer_handle(),
- process(), &renderer_handle, 0, FALSE,
+ process().handle(), &renderer_handle, 0, FALSE,
DUPLICATE_SAME_ACCESS);
DCHECK(result);
@@ -826,7 +801,7 @@ void PluginProcessHost::OnChannelCreated(int process_id,
== process_id) {
ReplyToRenderer(sent_requests_[i].renderer_message_filter_.get(),
channel_name,
- plugin_path(),
+ info_.path,
sent_requests_[i].reply_msg);
sent_requests_.erase(sent_requests_.begin() + i);
@@ -874,7 +849,7 @@ void PluginProcessHost::OnPluginMessage(
DCHECK(MessageLoop::current() ==
ChromeThread::GetMessageLoop(ChromeThread::IO));
- ChromePluginLib *chrome_plugin = ChromePluginLib::Find(plugin_path_);
+ ChromePluginLib *chrome_plugin = ChromePluginLib::Find(info_.path);
if (chrome_plugin) {
void *data_ptr = const_cast<void*>(reinterpret_cast<const void*>(&data[0]));
uint32 data_len = static_cast<uint32>(data.size());
@@ -885,7 +860,7 @@ void PluginProcessHost::OnPluginMessage(
void PluginProcessHost::OnCreateWindow(HWND parent, IPC::Message* reply_msg) {
// Need to create this window on the UI thread.
plugin_service_->main_message_loop()->PostTask(FROM_HERE,
- new CreateWindowTask(plugin_path_, parent, reply_msg));
+ new CreateWindowTask(info_.path, parent, reply_msg));
}
void PluginProcessHost::OnDestroyWindow(HWND window) {
@@ -897,4 +872,3 @@ void PluginProcessHost::Shutdown() {
Send(new PluginProcessMsg_BrowserShutdown);
}
-
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index 45eeaab..74e86fc 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -10,12 +10,13 @@
#include "base/basictypes.h"
#include "base/id_map.h"
#include "base/object_watcher.h"
-#include "base/process.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
#include "chrome/browser/net/resolve_proxy_msg_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include "chrome/common/child_process_info.h"
#include "chrome/common/ipc_channel_proxy.h"
+#include "webkit/glue/webplugin.h"
class PluginService;
class PluginProcessHost;
@@ -32,7 +33,8 @@ class GURL;
// starting the plugin process when a plugin is created that doesn't already
// have a process. After that, most of the communication is directly between
// the renderer and plugin processes.
-class PluginProcessHost : public IPC::Channel::Listener,
+class PluginProcessHost : public ChildProcessInfo,
+ public IPC::Channel::Listener,
public IPC::Message::Sender,
public base::ObjectWatcher::Delegate,
public ResolveProxyMsgHelper::Delegate {
@@ -44,7 +46,7 @@ class PluginProcessHost : public IPC::Channel::Listener,
// be called before the object can be used. If plugin_path is the
// ActiveX-shim, then activex_clsid is the class id of ActiveX control,
// otherwise activex_clsid is ignored.
- bool Init(const FilePath& plugin_path,
+ bool Init(const WebPluginInfo& info,
const std::string& activex_clsid,
const std::wstring& locale);
@@ -64,9 +66,6 @@ class PluginProcessHost : public IPC::Channel::Listener,
int result,
const std::string& proxy_list);
- // Getter to the process, may return NULL if there is no connection.
- HANDLE process() { return process_.handle(); }
-
// Tells the plugin process to create a new channel for communication with a
// renderer. When the plugin process responds with the channel name,
// reply_msg is used to send the name to the renderer.
@@ -74,8 +73,6 @@ class PluginProcessHost : public IPC::Channel::Listener,
const std::string& mime_type,
IPC::Message* reply_msg);
- const FilePath& plugin_path() const { return plugin_path_; }
-
// Sends the reply to an open channel request to the renderer with the given
// channel name.
static void ReplyToRenderer(ResourceMessageFilter* renderer_message_filter,
@@ -140,9 +137,6 @@ class PluginProcessHost : public IPC::Channel::Listener,
// the plugin process, but haven't heard back about yet.
std::vector<ChannelRequest> sent_requests_;
- // The handle to our plugin process.
- base::Process process_;
-
// Used to watch the plugin process handle.
base::ObjectWatcher watcher_;
@@ -156,8 +150,8 @@ class PluginProcessHost : public IPC::Channel::Listener,
// IPC Channel's id.
std::wstring channel_id_;
- // Path to the file of that plugin.
- FilePath plugin_path_;
+ // Information about the plugin.
+ WebPluginInfo info_;
PluginService* plugin_service_;
diff --git a/chrome/browser/plugin_process_info.h b/chrome/browser/plugin_process_info.h
deleted file mode 100644
index 90fc4f0..0000000
--- a/chrome/browser/plugin_process_info.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-// This class contains some information about a plugin process.
-// It is used as the source to notifications about plugin process connections/
-// disconnections.
-// It has a copy constructor and assignment operator so that it can be copied.
-// It also defines the < operator so that it can be used as a key in a std::map.
-
-#ifndef CHROME_BROWSER_PLUGIN_PROCESS_INFO_H__
-#define CHROME_BROWSER_PLUGIN_PROCESS_INFO_H__
-
-#include <string>
-#include "windows.h"
-
-#include "base/file_path.h"
-
-class PluginProcessInfo {
- public:
- PluginProcessInfo(FilePath plugin_path, HANDLE process)
- : plugin_path_(plugin_path),
- process_(process) {
- }
-
- PluginProcessInfo(const PluginProcessInfo& ppi) {
- plugin_path_ = ppi.plugin_path_;
- process_ = ppi.process_;
- }
-
- ~PluginProcessInfo() { };
-
- PluginProcessInfo&
- PluginProcessInfo::operator=(const PluginProcessInfo& ppi) {
- if (this != &ppi) {
- plugin_path_ = ppi.plugin_path_;
- process_ = ppi.process_;
- }
- return *this;
- }
-
- // We define the < operator so that the PluginProcessInfo can be used as a key
- // in a std::map.
- bool operator <(const PluginProcessInfo& rhs) const {
- if (process_ != rhs.process_)
- return process_ < rhs.process_;
- return plugin_path_ < rhs.plugin_path_;
- }
-
- bool operator ==(const PluginProcessInfo& rhs) const {
- return (process_ == rhs.process_) && (plugin_path_ == rhs.plugin_path_);
- }
-
- FilePath plugin_path() const { return plugin_path_; }
-
- HANDLE process() const { return process_; }
-
- private:
- FilePath plugin_path_;
- HANDLE process_;
-};
-
-#endif // #ifndef CHROME_BROWSER_PLUGIN_PROCESS_INFO_H__
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index aeec45b..cf72d07 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -85,9 +85,15 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess(
if (plugin_host)
return plugin_host;
+ WebPluginInfo info;
+ if (!GetPluginInfoByPath(plugin_path, &info)) {
+ DCHECK(false);
+ return NULL;
+ }
+
// This plugin isn't loaded by any plugin process, so create a new process.
plugin_host = new PluginProcessHost(this);
- if (!plugin_host->Init(plugin_path, clsid, ui_locale_)) {
+ if (!plugin_host->Init(info, clsid, ui_locale_)) {
DCHECK(false); // Init is not expected to fail
delete plugin_host;
return NULL;
diff --git a/chrome/browser/resources/about_memory.html b/chrome/browser/resources/about_memory.html
index a12231e4..ddae623 100644
--- a/chrome/browser/resources/about_memory.html
+++ b/chrome/browser/resources/about_memory.html
@@ -613,12 +613,12 @@ function enableHelpTooltips() {
<span class='th' jseval="addToSum('tot_comm_map', $this.comm_map)" jscontent="comm_map"></span><span class='k'>k</span>
</td>
</tr>
- <tr jsselect="renderer_data">
+ <tr jsselect="child_data">
<td class='pid'>
<span class='th' jscontent="pid"></span>
</td>
<td class='name'>
- <div jscontent="renderer_id"></div>
+ <div jscontent="child_name"></div>
<div jsselect="titles">
<span jscontent="$this"></span><br>
</div>
diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc
index 54704a9..a64352c 100644
--- a/chrome/browser/task_manager.cc
+++ b/chrome/browser/task_manager.cc
@@ -74,10 +74,10 @@ TaskManagerTableModel::TaskManagerTableModel(TaskManager* task_manager)
new TaskManagerWebContentsResourceProvider(task_manager);
wc_provider->AddRef();
providers_.push_back(wc_provider);
- TaskManagerPluginProcessResourceProvider* plugin_provider =
- new TaskManagerPluginProcessResourceProvider(task_manager);
- plugin_provider->AddRef();
- providers_.push_back(plugin_provider);
+ TaskManagerChildProcessResourceProvider* child_process_provider =
+ new TaskManagerChildProcessResourceProvider(task_manager);
+ child_process_provider->AddRef();
+ providers_.push_back(child_process_provider);
}
TaskManagerTableModel::~TaskManagerTableModel() {
diff --git a/chrome/browser/task_manager_resource_providers.cc b/chrome/browser/task_manager_resource_providers.cc
index d16085e..aa23d6e 100644
--- a/chrome/browser/task_manager_resource_providers.cc
+++ b/chrome/browser/task_manager_resource_providers.cc
@@ -255,74 +255,64 @@ void TaskManagerWebContentsResourceProvider::Observe(NotificationType type,
}
////////////////////////////////////////////////////////////////////////////////
-// TaskManagerPluginProcessResource class
+// TaskManagerChildProcessResource class
////////////////////////////////////////////////////////////////////////////////
-SkBitmap* TaskManagerPluginProcessResource::default_icon_ = NULL;
+SkBitmap* TaskManagerChildProcessResource::default_icon_ = NULL;
-TaskManagerPluginProcessResource::TaskManagerPluginProcessResource(
- PluginProcessInfo plugin_proc)
- : plugin_process_(plugin_proc),
+TaskManagerChildProcessResource::TaskManagerChildProcessResource(
+ ChildProcessInfo child_proc)
+ : child_process_(child_proc),
title_(),
network_usage_support_(false) {
- pid_ = base::GetProcId(plugin_proc.process());
+ // We cache the process id because it's not cheap to calculate, and it won't
+ // be available when we get the plugin disconnected notification.
+ pid_ = child_proc.process().pid();
if (!default_icon_) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
default_icon_ = rb.GetBitmapNamed(IDR_PLUGIN);
+ // TODO(jabdelmalek): use different icon for web workers.
}
}
-TaskManagerPluginProcessResource::~TaskManagerPluginProcessResource() {
+TaskManagerChildProcessResource::~TaskManagerChildProcessResource() {
}
// TaskManagerResource methods:
-std::wstring TaskManagerPluginProcessResource::GetTitle() const {
- if (title_.empty()) {
- std::wstring plugin_name;
- WebPluginInfo info;
- if (PluginService::GetInstance()->
- GetPluginInfoByPath(plugin_process_.plugin_path(), &info))
- plugin_name = info.name;
- else
- plugin_name = l10n_util::GetString(IDS_TASK_MANAGER_UNKNOWN_PLUGIN_NAME);
- // Explicitly mark plugin_name as LTR if there is no strong RTL character,
- // to avoid the wrong concatenation result similar to "!Yahoo! Mail: the
- // best web-based Email: NIGULP", in which "NIGULP" stands for the Hebrew
- // or Arabic word for "plugin".
- l10n_util::AdjustStringForLocaleDirection(plugin_name, &plugin_name);
- title_ = l10n_util::GetStringF(IDS_TASK_MANAGER_PLUGIN_PREFIX,
- plugin_name);
- }
+std::wstring TaskManagerChildProcessResource::GetTitle() const {
+ if (title_.empty())
+ title_ = child_process_.GetLocalizedTitle();
+
return title_;
}
-SkBitmap TaskManagerPluginProcessResource::GetIcon() const {
+SkBitmap TaskManagerChildProcessResource::GetIcon() const {
return *default_icon_;
}
-HANDLE TaskManagerPluginProcessResource::GetProcess() const {
- return plugin_process_.process();
+HANDLE TaskManagerChildProcessResource::GetProcess() const {
+ return (const_cast<ChildProcessInfo&>(child_process_)).process().handle();
}
////////////////////////////////////////////////////////////////////////////////
-// TaskManagerPluginProcessResourceProvider class
+// TaskManagerChildProcessResourceProvider class
////////////////////////////////////////////////////////////////////////////////
-TaskManagerPluginProcessResourceProvider::
- TaskManagerPluginProcessResourceProvider(TaskManager* task_manager)
+TaskManagerChildProcessResourceProvider::
+ TaskManagerChildProcessResourceProvider(TaskManager* task_manager)
: task_manager_(task_manager),
updating_(false),
ui_loop_(MessageLoop::current()) {
}
-TaskManagerPluginProcessResourceProvider::
- ~TaskManagerPluginProcessResourceProvider() {
+TaskManagerChildProcessResourceProvider::
+ ~TaskManagerChildProcessResourceProvider() {
}
-TaskManager::Resource* TaskManagerPluginProcessResourceProvider::GetResource(
+TaskManager::Resource* TaskManagerChildProcessResourceProvider::GetResource(
int origin_pid,
int render_process_host_id,
int routing_id) {
- std::map<int, TaskManagerPluginProcessResource*>::iterator iter =
+ std::map<int, TaskManagerChildProcessResource*>::iterator iter =
pid_to_resources_.find(origin_pid);
if (iter != pid_to_resources_.end())
return iter->second;
@@ -330,33 +320,33 @@ TaskManager::Resource* TaskManagerPluginProcessResourceProvider::GetResource(
return NULL;
}
-void TaskManagerPluginProcessResourceProvider::StartUpdating() {
+void TaskManagerChildProcessResourceProvider::StartUpdating() {
DCHECK(!updating_);
updating_ = true;
// Register for notifications to get new plugin processes.
NotificationService* service = NotificationService::current();
- service->AddObserver(this, NotificationType::PLUGIN_PROCESS_HOST_CONNECTED,
+ service->AddObserver(this, NotificationType::CHILD_PROCESS_HOST_CONNECTED,
NotificationService::AllSources());
- service->AddObserver(this, NotificationType::PLUGIN_PROCESS_HOST_DISCONNECTED,
+ service->AddObserver(this, NotificationType::CHILD_PROCESS_HOST_DISCONNECTED,
NotificationService::AllSources());
// Get the existing plugins
MessageLoop* io_loop_ = g_browser_process->io_thread()->message_loop();
io_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &TaskManagerPluginProcessResourceProvider::RetrievePluginProcessInfo));
+ &TaskManagerChildProcessResourceProvider::RetrieveChildProcessInfo));
}
-void TaskManagerPluginProcessResourceProvider::StopUpdating() {
+void TaskManagerChildProcessResourceProvider::StopUpdating() {
DCHECK(updating_);
updating_ = false;
// Unregister for notifications to get new plugin processes.
NotificationService* service = NotificationService::current();
- service->RemoveObserver(this, NotificationType::PLUGIN_PROCESS_HOST_CONNECTED,
+ service->RemoveObserver(this, NotificationType::CHILD_PROCESS_HOST_CONNECTED,
NotificationService::AllSources());
service->RemoveObserver(this,
- NotificationType::PLUGIN_PROCESS_HOST_DISCONNECTED,
+ NotificationType::CHILD_PROCESS_HOST_DISCONNECTED,
NotificationService::AllSources());
// Delete all the resources.
@@ -364,19 +354,19 @@ void TaskManagerPluginProcessResourceProvider::StopUpdating() {
resources_.clear();
pid_to_resources_.clear();
- existing_plugin_process_info.clear();
+ existing_child_process_info_.clear();
}
-void TaskManagerPluginProcessResourceProvider::Observe(
+void TaskManagerChildProcessResourceProvider::Observe(
NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
switch (type.value) {
- case NotificationType::PLUGIN_PROCESS_HOST_CONNECTED:
- Add(*Details<PluginProcessInfo>(details).ptr());
+ case NotificationType::CHILD_PROCESS_HOST_CONNECTED:
+ Add(*Details<ChildProcessInfo>(details).ptr());
break;
- case NotificationType::PLUGIN_PROCESS_HOST_DISCONNECTED:
- Remove(*Details<PluginProcessInfo>(details).ptr());
+ case NotificationType::CHILD_PROCESS_HOST_DISCONNECTED:
+ Remove(*Details<ChildProcessInfo>(details).ptr());
break;
default:
NOTREACHED() << "Unexpected notification.";
@@ -384,41 +374,41 @@ void TaskManagerPluginProcessResourceProvider::Observe(
}
}
-void TaskManagerPluginProcessResourceProvider::Add(
- PluginProcessInfo plugin_process_info) {
+void TaskManagerChildProcessResourceProvider::Add(
+ ChildProcessInfo child_process_info) {
if (!updating_)
return;
- std::map<PluginProcessInfo, TaskManagerPluginProcessResource*>::
- const_iterator iter = resources_.find(plugin_process_info);
+ std::map<ChildProcessInfo, TaskManagerChildProcessResource*>::
+ const_iterator iter = resources_.find(child_process_info);
if (iter != resources_.end()) {
- // The case may happen that we have added a plugin_process_host as part of
+ // The case may happen that we have added a child_process_info as part of
// the iteration performed during StartUpdating() call but the notification
// that it has connected was not fired yet. So when the notification
// happens, we already know about this plugin and just ignore it.
return;
}
- AddToTaskManager(plugin_process_info);
+ AddToTaskManager(child_process_info);
}
-void TaskManagerPluginProcessResourceProvider::Remove(
- PluginProcessInfo plugin_process_info) {
+void TaskManagerChildProcessResourceProvider::Remove(
+ ChildProcessInfo child_process_info) {
if (!updating_)
return;
- std::map<PluginProcessInfo, TaskManagerPluginProcessResource*>
- ::iterator iter = resources_.find(plugin_process_info);
+ std::map<ChildProcessInfo, TaskManagerChildProcessResource*>
+ ::iterator iter = resources_.find(child_process_info);
if (iter == resources_.end()) {
- // PluginProcessHost disconnection notifications are asynchronous, so we
+ // ChildProcessInfo disconnection notifications are asynchronous, so we
// might be notified for a plugin we don't know anything about (if it was
// closed before the task manager was shown and destroyed after that).
return;
}
// Remove the resource from the Task Manager.
- TaskManagerPluginProcessResource* resource = iter->second;
+ TaskManagerChildProcessResource* resource = iter->second;
task_manager_->RemoveResource(resource);
// Remove it from the provider.
resources_.erase(iter);
// Remove it from our pid map.
- std::map<int, TaskManagerPluginProcessResource*>::iterator pid_iter =
+ std::map<int, TaskManagerChildProcessResource*>::iterator pid_iter =
pid_to_resources_.find(resource->process_id());
DCHECK(pid_iter != pid_to_resources_.end());
if (pid_iter != pid_to_resources_.end())
@@ -428,37 +418,34 @@ void TaskManagerPluginProcessResourceProvider::Remove(
delete resource;
}
-void TaskManagerPluginProcessResourceProvider::AddToTaskManager(
- PluginProcessInfo plugin_process_info) {
- TaskManagerPluginProcessResource* resource =
- new TaskManagerPluginProcessResource(plugin_process_info);
- resources_[plugin_process_info] = resource;
- pid_to_resources_[base::GetProcId(plugin_process_info.process())] =
- resource;
+void TaskManagerChildProcessResourceProvider::AddToTaskManager(
+ ChildProcessInfo child_process_info) {
+ TaskManagerChildProcessResource* resource =
+ new TaskManagerChildProcessResource(child_process_info);
+ resources_[child_process_info] = resource;
+ pid_to_resources_[resource->process_id()] = resource;
task_manager_->AddResource(resource);
}
// The PluginProcessIterator has to be used from the IO thread.
-void TaskManagerPluginProcessResourceProvider::RetrievePluginProcessInfo() {
+void TaskManagerChildProcessResourceProvider::RetrieveChildProcessInfo() {
for (PluginProcessHostIterator iter; !iter.Done(); ++iter) {
- PluginProcessHost* plugin = const_cast<PluginProcessHost*>(*iter);
- DCHECK(plugin->process());
- PluginProcessInfo plugin_info(plugin->plugin_path(), plugin->process());
- existing_plugin_process_info.push_back(plugin_info);
+ const ChildProcessInfo* child = *iter;
+ existing_child_process_info_.push_back(*child);
}
// Now notify the UI thread that we have retrieved the PluginProcessHosts.
ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &TaskManagerPluginProcessResourceProvider::PluginProcessInfoRetreived));
+ &TaskManagerChildProcessResourceProvider::ChildProcessInfoRetreived));
}
// This is called on the UI thread.
-void TaskManagerPluginProcessResourceProvider::PluginProcessInfoRetreived() {
- std::vector<PluginProcessInfo>::const_iterator iter;
- for (iter = existing_plugin_process_info.begin();
- iter != existing_plugin_process_info.end(); ++iter) {
+void TaskManagerChildProcessResourceProvider::ChildProcessInfoRetreived() {
+ std::vector<ChildProcessInfo>::const_iterator iter;
+ for (iter = existing_child_process_info_.begin();
+ iter != existing_child_process_info_.end(); ++iter) {
Add(*iter);
}
- existing_plugin_process_info.clear();
+ existing_child_process_info_.clear();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/task_manager_resource_providers.h b/chrome/browser/task_manager_resource_providers.h
index 2fb0820..a56aed5 100644
--- a/chrome/browser/task_manager_resource_providers.h
+++ b/chrome/browser/task_manager_resource_providers.h
@@ -6,11 +6,10 @@
#define CHROME_BROWSER_TASK_MANAGER_RESOURCE_PROVIDERS_H_
#include "base/basictypes.h"
-#include "chrome/browser/plugin_process_info.h"
#include "chrome/browser/task_manager.h"
+#include "chrome/common/child_process_info.h"
#include "chrome/common/notification_observer.h"
-class PluginProcessHost;
class WebContents;
// These file contains the resource providers used in the task manager.
@@ -75,10 +74,10 @@ class TaskManagerWebContentsResourceProvider
DISALLOW_COPY_AND_ASSIGN(TaskManagerWebContentsResourceProvider);
};
-class TaskManagerPluginProcessResource : public TaskManager::Resource {
+class TaskManagerChildProcessResource : public TaskManager::Resource {
public:
- explicit TaskManagerPluginProcessResource(PluginProcessInfo plugin_proc);
- ~TaskManagerPluginProcessResource();
+ explicit TaskManagerChildProcessResource(ChildProcessInfo child_proc);
+ ~TaskManagerChildProcessResource();
// TaskManagerResource methods:
std::wstring GetTitle() const;
@@ -93,29 +92,29 @@ class TaskManagerPluginProcessResource : public TaskManager::Resource {
network_usage_support_ = true;
}
- // Returns the pid of the plugin process.
+ // Returns the pid of the child process.
int process_id() const { return pid_; }
private:
- PluginProcessInfo plugin_process_;
+ ChildProcessInfo child_process_;
int pid_;
mutable std::wstring title_;
bool network_usage_support_;
- // The icon painted for plugins.
+ // The icon painted for the child processs.
// TODO (jcampan): we should have plugin specific icons for well-known
// plugins.
static SkBitmap* default_icon_;
- DISALLOW_COPY_AND_ASSIGN(TaskManagerPluginProcessResource);
+ DISALLOW_COPY_AND_ASSIGN(TaskManagerChildProcessResource);
};
-class TaskManagerPluginProcessResourceProvider
+class TaskManagerChildProcessResourceProvider
: public TaskManager::ResourceProvider,
public NotificationObserver {
public:
- explicit TaskManagerPluginProcessResourceProvider(TaskManager* task_manager);
- virtual ~TaskManagerPluginProcessResourceProvider();
+ explicit TaskManagerChildProcessResourceProvider(TaskManager* task_manager);
+ virtual ~TaskManagerChildProcessResourceProvider();
virtual TaskManager::Resource* GetResource(int origin_pid,
int render_process_host_id,
@@ -128,38 +127,38 @@ class TaskManagerPluginProcessResourceProvider
const NotificationSource& source,
const NotificationDetails& details);
- // Retrieves the current PluginProcessInfo (performed in the IO thread).
- virtual void RetrievePluginProcessInfo();
+ // Retrieves the current ChildProcessInfo (performed in the IO thread).
+ virtual void RetrieveChildProcessInfo();
- // Notifies the UI thread that the PluginProcessInfo have been retrieved.
- virtual void PluginProcessInfoRetreived();
+ // Notifies the UI thread that the ChildProcessInfo have been retrieved.
+ virtual void ChildProcessInfoRetreived();
// Whether we are currently reporting to the task manager. Used to ignore
// notifications sent after StopUpdating().
bool updating_;
- // The list of PluginProcessInfo retrieved when starting the update.
- std::vector<PluginProcessInfo> existing_plugin_process_info;
+ // The list of ChildProcessInfo retrieved when starting the update.
+ std::vector<ChildProcessInfo> existing_child_process_info_;
private:
- void Add(PluginProcessInfo plugin_process_info);
- void Remove(PluginProcessInfo plugin_process_info);
+ void Add(ChildProcessInfo child_process_info);
+ void Remove(ChildProcessInfo child_process_info);
- void AddToTaskManager(PluginProcessInfo plugin_process_info);
+ void AddToTaskManager(ChildProcessInfo child_process_info);
TaskManager* task_manager_;
MessageLoop* ui_loop_;
- // Maps the actual resources (the PluginProcessInfo) to the Task Manager
+ // Maps the actual resources (the ChildProcessInfo) to the Task Manager
// resources.
- std::map<PluginProcessInfo, TaskManagerPluginProcessResource*> resources_;
+ std::map<ChildProcessInfo, TaskManagerChildProcessResource*> resources_;
// Maps the pids to the resources (used for quick access to the resource on
// byte read notifications).
- std::map<int, TaskManagerPluginProcessResource*> pid_to_resources_;
+ std::map<int, TaskManagerChildProcessResource*> pid_to_resources_;
- DISALLOW_COPY_AND_ASSIGN(TaskManagerPluginProcessResourceProvider);
+ DISALLOW_COPY_AND_ASSIGN(TaskManagerChildProcessResourceProvider);
};
class TaskManagerBrowserProcessResource : public TaskManager::Resource {
@@ -212,7 +211,7 @@ class TaskManagerBrowserProcessResourceProvider
bool updating_;
private:
- void AddToTaskManager(PluginProcessInfo plugin_process_info);
+ void AddToTaskManager(ChildProcessInfo child_process_info);
TaskManager* task_manager_;
TaskManagerBrowserProcessResource resource_;
diff --git a/chrome/common/child_process_info.cc b/chrome/common/child_process_info.cc
new file mode 100644
index 0000000..ca777bd
--- /dev/null
+++ b/chrome/common/child_process_info.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2009 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/common/child_process_info.h"
+
+#include "base/logging.h"
+#include "chrome/common/l10n_util.h"
+
+#include "generated_resources.h"
+
+std::wstring ChildProcessInfo::GetTypeNameInEnglish(
+ ChildProcessInfo::ProcessType type) {
+ switch (type) {
+ case BROWSER_PROCESS:
+ return L"Browser";
+ case RENDER_PROCESS:
+ return L"Tab";
+ case PLUGIN_PROCESS:
+ return L"Plug-in";
+ case WORKER_PROCESS:
+ return L"Web Worker";
+ case UNKNOWN_PROCESS:
+ default:
+ DCHECK(false) << "Unknown child process type!";
+ return L"Unknown";
+ }
+}
+
+std::wstring ChildProcessInfo::GetLocalizedTitle() const {
+ std::wstring title = name_;
+ if (type_ == ChildProcessInfo::PLUGIN_PROCESS && title.empty())
+ title = l10n_util::GetString(IDS_TASK_MANAGER_UNKNOWN_PLUGIN_NAME);
+
+ int message_id;
+ if (type_ == ChildProcessInfo::PLUGIN_PROCESS) {
+ message_id = IDS_TASK_MANAGER_PLUGIN_PREFIX;
+ } else if (type_ == ChildProcessInfo::WORKER_PROCESS) {
+ message_id = IDS_TASK_MANAGER_WORKER_PREFIX;
+ } else {
+ DCHECK(false) << "Need localized name for child process type.";
+ return title;
+ }
+
+ // Explicitly mark name as LTR if there is no strong RTL character,
+ // to avoid the wrong concatenation result similar to "!Yahoo! Mail: the
+ // best web-based Email: NIGULP", in which "NIGULP" stands for the Hebrew
+ // or Arabic word for "plugin".
+ l10n_util::AdjustStringForLocaleDirection(title, &title);
+ return l10n_util::GetStringF(message_id, title);
+}
diff --git a/chrome/common/child_process_info.h b/chrome/common/child_process_info.h
new file mode 100644
index 0000000..2007bcb
--- /dev/null
+++ b/chrome/common/child_process_info.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_COMMON_CHILD_PROCESS_INFO_H_
+#define CHROME_COMMON_CHILD_PROCESS_INFO_H_
+
+#include <string>
+#include "base/basictypes.h"
+#include "base/process.h"
+
+// Holds information about a child process.
+class ChildProcessInfo {
+ public:
+ enum ProcessType {
+ BROWSER_PROCESS,
+ RENDER_PROCESS,
+ PLUGIN_PROCESS,
+ WORKER_PROCESS,
+ UNKNOWN_PROCESS,
+ };
+
+ // Returns the type of the process.
+ ProcessType type() const { return type_; }
+
+ // Returns the name of the process. i.e. for plugins it might be Flash, while
+ // for workers it might be the domain that it's from.
+ std::wstring name() const { return name_; }
+
+ // Getter to the process.
+ base::Process& process() { return process_; }
+
+ // Returns an English name of the process type, should only be used for non
+ // user-visible strings, or debugging pages like about:memory.
+ static std::wstring GetTypeNameInEnglish(ProcessType type);
+
+ // Returns a localized title for the child process. For example, a plugin
+ // process would be "Plug-in: Flash" when name is "Flash".
+ std::wstring GetLocalizedTitle() const;
+
+ // We define the < operator so that the ChildProcessInfo can be used as a key
+ // in a std::map.
+ bool operator <(const ChildProcessInfo& rhs) const {
+ if (process_.handle() != rhs.process_.handle())
+ return process_ .handle() < rhs.process_.handle();
+ return name_ < rhs.name_;
+ }
+
+ bool operator ==(const ChildProcessInfo& rhs) const {
+ return (process_.handle() == rhs.process_.handle()) && (name_ == rhs.name_);
+ }
+
+ protected:
+ void set_type(ProcessType type) { type_ = type; }
+ void set_name(const std::wstring& name) { name_ = name; }
+
+ private:
+ ProcessType type_;
+ std::wstring name_;
+
+ // The handle to the process.
+ base::Process process_;
+};
+
+#endif // CHROME_COMMON_CHILD_PROCESS_INFO_H_
+
diff --git a/chrome/common/common.scons b/chrome/common/common.scons
index 829da06..832485f 100644
--- a/chrome/common/common.scons
+++ b/chrome/common/common.scons
@@ -106,6 +106,8 @@ input_files = ChromeFileList([
'animation.h',
'child_process.cc',
'child_process.h',
+ 'child_process_info.cc',
+ 'child_process_info.h',
'chrome_constants.cc',
'chrome_constants.h',
'chrome_counters.cc',
diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj
index 44c9962..00282224 100644
--- a/chrome/common/common.vcproj
+++ b/chrome/common/common.vcproj
@@ -342,6 +342,14 @@
>
</File>
<File
+ RelativePath=".\child_process_info.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\child_process_info.h"
+ >
+ </File>
+ <File
RelativePath=".\chrome_constants.cc"
>
</File>
@@ -525,7 +533,7 @@
RelativePath=".\notification_details.h"
>
</File>
- <File
+ <File
RelativePath=".\notification_observer.h"
>
</File>
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 7924866..5e59742 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -319,47 +319,35 @@ class NotificationType {
// guaranteed to be valid after the notification.
WEB_CACHE_STATS_OBSERVED,
- // Plugins -----------------------------------------------------------------
+ // Child Processes ---------------------------------------------------------
- // This notification is sent when a plugin process host has connected to a
- // plugin process. There is no usable source, since it is sent from an
+ // This notification is sent when a child process host has connected to a
+ // child process. There is no usable source, since it is sent from an
// ephemeral task; register for AllSources() to receive this notification.
- // The details are in a Details<PluginProcessInfo> with a pointer to a
- // plug-in process info for the plugin, that is only valid for the time of
- // the notification (don't keep this pointer around, make a copy of the
- // object if you need to keep it).
- PLUGIN_PROCESS_HOST_CONNECTED,
-
- // This message is sent after a PluginProcessHost is disconnected from the
- // plugin process. There is no usable source, since it is sent from an
+ // The details are in a Details<ChildProcessInfo>.
+ CHILD_PROCESS_HOST_CONNECTED,
+
+ // This message is sent after a ChildProcessHost is disconnected from the
+ // child process. There is no usable source, since it is sent from an
// ephemeral task; register for AllSources() to receive this notification.
- // The details are in a Details<PluginProcessInfo> with a pointer to a
- // plug-in process info for the plugin, that is only valid for the time of
- // the notification (don't keep this pointer around, make a copy of the
- // object if you need to keep it).
- PLUGIN_PROCESS_HOST_DISCONNECTED,
+ // The details are in a Details<ChildProcessInfo>.
+ CHILD_PROCESS_HOST_DISCONNECTED,
- // This message is sent when a plugin process disappears unexpectedly.
+ // This message is sent when a child process disappears unexpectedly.
// There is no usable source, since it is sent from an ephemeral task;
// register for AllSources() to receive this notification. The details are
- // in a Details<PluginProcessInfo> with a pointer to a plug-in process info
- // for the plugin, that is only valid for the time of the notification
- // (don't keep this pointer around, make a copy of the object if you need
- // to keep it).
- PLUGIN_PROCESS_CRASHED,
+ // in a Details<ChildProcessInfo>.
+ CHILD_PROCESS_CRASHED,
- // This message indicates that an instance of a particular plugin was
+ // This message indicates that an instance of a particular child was
// created in a page. (If one page contains several regions rendered by
- // the same plugin, this notification will occur once for each region
+ // the same child, this notification will occur once for each region
// during the page load.)
//
// There is no usable source, since it is sent from an ephemeral task;
// register for AllSources() to receive this notification. The details are
- // in a Details<PluginProcessInfo> with a pointer to a plug-in process info
- // for the plugin, that is only valid for the time of the notification
- // (don't keep this pointer around, make a copy of the object if you need
- // to keep it).
- PLUGIN_INSTANCE_CREATED,
+ // in a Details<ChildProcessInfo>.
+ CHILD_INSTANCE_CREATED,
// This is sent when network interception is disabled for a plugin, or the
// plugin is unloaded. This should only be sent/received on the browser IO
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index f00406d..8c8dc76 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -328,7 +328,7 @@ const wchar_t kStabilityUptimeSec[] =
// This is the location of a list of dictionaries of plugin stability stats.
const wchar_t kStabilityPluginStats[] =
- L"user_experience_metrics.stability.plugin_stats";
+ L"user_experience_metrics.stability.plugin_stats2";
// Number of times the renderer has become non-responsive since the last
// report.
@@ -353,7 +353,7 @@ const wchar_t kStabilityDebuggerNotPresent[] =
// The keys below are used for the dictionaries in the
// kStabilityPluginStats list.
-const wchar_t kStabilityPluginPath[] = L"path";
+const wchar_t kStabilityPluginName[] = L"name";
const wchar_t kStabilityPluginLaunches[] = L"launches";
const wchar_t kStabilityPluginInstances[] = L"instances";
const wchar_t kStabilityPluginCrashes[] = L"crashes";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 6e09d74..501b3e0 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -116,7 +116,7 @@ extern const wchar_t kSecurityRendererOnSboxDesktop[];
extern const wchar_t kSecurityRendererOnDefaultDesktop[];
extern const wchar_t kStabilityPluginStats[];
-extern const wchar_t kStabilityPluginPath[];
+extern const wchar_t kStabilityPluginName[];
extern const wchar_t kStabilityPluginLaunches[];
extern const wchar_t kStabilityPluginInstances[];
extern const wchar_t kStabilityPluginCrashes[];