diff options
62 files changed, 799 insertions, 493 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 3a0f040..3fb70c9 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -34,7 +34,6 @@ include_rules = [ "+content/browser/accessibility/browser_accessibility_manager.h", "+content/browser/accessibility/browser_accessibility_state.h", "+content/browser/appcache/chrome_appcache_service.h", - "+content/browser/browser_child_process_host.h", "+content/browser/browser_thread_impl.h", "+content/browser/browser_url_handler.h", "+content/browser/cert_store.h", diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index e10c260..d47e26e 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -117,6 +117,8 @@ #include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/interstitial_page.h" +#include "content/public/browser/browser_child_process_host_iterator.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" @@ -151,6 +153,7 @@ using automation::Error; using automation::ErrorCode; using automation_util::SendErrorIfModalDialogActive; +using content::BrowserChildProcessHostIterator; using content::BrowserThread; using content::ChildProcessHost; using content::DownloadItem; @@ -2773,20 +2776,18 @@ void TestingAutomationProvider::PerformActionOnInfobar( namespace { // Gets info about BrowserChildProcessHost. Must run on IO thread to -// honor the semantics of BrowserChildProcessHost. +// honor the semantics of BrowserChildProcessHostIterator. // Used by AutomationProvider::GetBrowserInfo(). void GetChildProcessHostInfo(ListValue* child_processes) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) { - // Only add processes which are already started, - // since we need their handle. - if ((*iter)->data().handle == base::kNullProcessHandle) + for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { + // Only add processes which are already started, since we need their handle. + if (iter.GetData().handle == base::kNullProcessHandle) continue; DictionaryValue* item = new DictionaryValue; - item->SetString("name", iter->data().name); + item->SetString("name", iter.GetData().name); item->SetString("type", - content::GetProcessTypeNameInEnglish(iter->data().type)); - item->SetInteger("pid", base::GetProcId(iter->data().handle)); + content::GetProcessTypeNameInEnglish(iter.GetData().type)); + item->SetInteger("pid", base::GetProcId(iter.GetData().handle)); child_processes->Append(item); } } diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 2f45144..ba2bd92 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -66,7 +66,6 @@ #include "chrome/common/switch_utils.h" #include "chrome/common/url_constants.h" #include "chrome/installer/util/google_update_constants.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/child_process_security_policy.h" #include "content/browser/download/download_status_updater.h" #include "content/browser/download/mhtml_generation_manager.h" diff --git a/chrome/browser/debugger/devtools_sanity_unittest.cc b/chrome/browser/debugger/devtools_sanity_unittest.cc index 0852321..41363e5 100644 --- a/chrome/browser/debugger/devtools_sanity_unittest.cc +++ b/chrome/browser/debugger/devtools_sanity_unittest.cc @@ -25,6 +25,8 @@ #include "chrome/test/base/ui_test_utils.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/worker_host/worker_process_host.h" +#include "content/public/browser/browser_child_process_host_iterator.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/devtools_agent_host_registry.h" #include "content/public/browser/devtools_client_host.h" @@ -292,7 +294,7 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest { virtual void WorkerCreated ( WorkerProcessHost* process, const WorkerProcessHost::WorkerInstance& instance) OVERRIDE { - worker_data_->worker_process_id = process->data().id; + worker_data_->worker_process_id = process->GetData().id; worker_data_->worker_route_id = instance.worker_route_id(); WorkerService::GetInstance()->RemoveObserver(this); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, @@ -323,7 +325,7 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest { virtual void WorkerDestroyed( WorkerProcessHost* process, int worker_route_id) OVERRIDE { - ASSERT_EQ(worker_data_->worker_process_id, process->data().id); + ASSERT_EQ(worker_data_->worker_process_id, process->GetData().id); ASSERT_EQ(worker_data_->worker_route_id, worker_route_id); WorkerService::GetInstance()->RemoveObserver(this); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, @@ -349,11 +351,9 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest { static void TerminateWorkerOnIOThread( scoped_refptr<WorkerData> worker_data) { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - if (iter->data().id == worker_data->worker_process_id) { - WorkerProcessHost* host = static_cast<WorkerProcessHost*>(*iter); - host->TerminateWorker(worker_data->worker_route_id); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter.GetData().id == worker_data->worker_process_id) { + iter->TerminateWorker(worker_data->worker_route_id); WorkerService::GetInstance()->AddObserver( new WorkerTerminationObserver(worker_data)); return; @@ -371,14 +371,12 @@ class WorkerDevToolsSanityTest : public InProcessBrowserTest { static void WaitForFirstSharedWorkerOnIOThread( scoped_refptr<WorkerData> worker_data) { - BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - for (; !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - const WorkerProcessHost::Instances& instances = worker->instances(); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + const WorkerProcessHost::Instances& instances = iter->instances(); for (WorkerProcessHost::Instances::const_iterator i = instances.begin(); i != instances.end(); ++i) { - worker_data->worker_process_id = worker->data().id; + worker_data->worker_process_id = iter.GetData().id; worker_data->worker_route_id = i->worker_route_id(); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 03e2c3c..6333a30 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -10,6 +10,7 @@ #include "base/base64.h" #include "base/bind.h" #include "base/memory/ref_counted_memory.h" +#include "base/message_loop.h" #include "base/stl_util.h" #include "base/string16.h" #include "base/string_number_conversions.h" diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc b/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc index 68bc2e9..5e19010 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc @@ -4,6 +4,7 @@ #include "base/file_util.h" #include "base/memory/ref_counted.h" +#include "base/message_loop.h" #include "base/path_service.h" #include "base/scoped_temp_dir.h" #include "base/scoped_temp_dir.h" diff --git a/chrome/browser/intents/web_intents_registry_unittest.cc b/chrome/browser/intents/web_intents_registry_unittest.cc index 3957064..a6de0bb 100644 --- a/chrome/browser/intents/web_intents_registry_unittest.cc +++ b/chrome/browser/intents/web_intents_registry_unittest.cc @@ -4,6 +4,7 @@ #include "base/file_util.h" #include "base/json/json_value_serializer.h" +#include "base/message_loop.h" #include "base/path_service.h" #include "base/scoped_temp_dir.h" #include "base/utf_string_conversions.h" diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc index df2d39c..5f5a9ee 100644 --- a/chrome/browser/memory_details.cc +++ b/chrome/browser/memory_details.cc @@ -16,7 +16,8 @@ #include "chrome/common/chrome_view_type.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/url_constants.h" -#include "content/browser/browser_child_process_host.h" +#include "content/public/browser/browser_child_process_host_iterator.h" +#include "content/public/browser/child_process_data.h" #include "content/browser/renderer_host/backing_store_manager.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/public/browser/browser_thread.h" @@ -35,6 +36,7 @@ #include "content/browser/zygote_host_linux.h" #endif +using content::BrowserChildProcessHostIterator; using content::BrowserThread; using content::NavigationEntry; using content::WebContents; @@ -132,15 +134,15 @@ void MemoryDetails::CollectChildInfoOnIOThread() { std::vector<ProcessMemoryInformation> child_info; // Collect the list of child processes. - for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) { + for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { ProcessMemoryInformation info; - info.pid = base::GetProcId(iter->data().handle); + info.pid = base::GetProcId(iter.GetData().handle); if (!info.pid) continue; - info.type = iter->data().type; + info.type = iter.GetData().type; info.renderer_type = ProcessMemoryInformation::RENDERER_UNKNOWN; - info.titles.push_back(iter->data().name); + info.titles.push_back(iter.GetData().name); child_info.push_back(info); } diff --git a/chrome/browser/memory_details_linux.cc b/chrome/browser/memory_details_linux.cc index d4baa68..0d47086 100644 --- a/chrome/browser/memory_details_linux.cc +++ b/chrome/browser/memory_details_linux.cc @@ -18,7 +18,6 @@ #include "base/utf_string_conversions.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/url_constants.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/zygote_host_linux.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/process_type.h" diff --git a/chrome/browser/memory_details_mac.cc b/chrome/browser/memory_details_mac.cc index 5d9ab92..d005150 100644 --- a/chrome/browser/memory_details_mac.cc +++ b/chrome/browser/memory_details_mac.cc @@ -20,7 +20,6 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/url_constants.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/renderer_host/backing_store_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/process_type.h" diff --git a/chrome/browser/memory_details_win.cc b/chrome/browser/memory_details_win.cc index 09cd799..0e1da5e4 100644 --- a/chrome/browser/memory_details_win.cc +++ b/chrome/browser/memory_details_win.cc @@ -15,7 +15,6 @@ #include "base/win/windows_version.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/url_constants.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/renderer_host/backing_store_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/process_type.h" diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc index 305c930..c0cf20b 100644 --- a/chrome/browser/metrics/metrics_service.cc +++ b/chrome/browser/metrics/metrics_service.cc @@ -177,6 +177,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "content/browser/load_notification_details.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_process_host.h" @@ -196,6 +197,7 @@ using base::Time; using content::BrowserThread; +using content::ChildProcessData; using content::PluginService; // Check to see that we're being called on only one thread. @@ -1335,7 +1337,7 @@ void MetricsService::LogChildProcessChange( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - content::Details<content::ChildProcessData> child_details(details); + content::Details<ChildProcessData> child_details(details); const string16& child_name = child_details->name; if (child_process_stats_buffer_.find(child_name) == diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc index d64c1ea..186e15e 100644 --- a/chrome/browser/nacl_host/nacl_broker_host_win.cc +++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc @@ -14,11 +14,13 @@ #include "chrome/common/logging_chrome.h" #include "chrome/common/nacl_cmd_line.h" #include "chrome/common/nacl_messages.h" +#include "content/public/browser/browser_child_process_host.h" #include "content/public/common/child_process_host.h" NaClBrokerHost::NaClBrokerHost() - : BrowserChildProcessHost(content::PROCESS_TYPE_NACL_BROKER), - stopping_(false) { + : stopping_(false) { + process_.reset(content::BrowserChildProcessHost::Create( + content::PROCESS_TYPE_NACL_BROKER, this)); } NaClBrokerHost::~NaClBrokerHost() { @@ -26,7 +28,7 @@ NaClBrokerHost::~NaClBrokerHost() { bool NaClBrokerHost::Init() { // Create the channel that will be used for communicating with the broker. - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -45,7 +47,7 @@ bool NaClBrokerHost::Init() { if (logging::DialogsAreSuppressed()) cmd_line->AppendSwitch(switches::kNoErrorDialogs); - BrowserChildProcessHost::Launch(FilePath(), cmd_line); + process_->Launch(FilePath(), cmd_line); return true; } @@ -60,7 +62,8 @@ bool NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) { bool NaClBrokerHost::LaunchLoader( const std::wstring& loader_channel_id) { - return Send(new NaClProcessMsg_LaunchLoaderThroughBroker(loader_channel_id)); + return process_->Send( + new NaClProcessMsg_LaunchLoaderThroughBroker(loader_channel_id)); } void NaClBrokerHost::OnLoaderLaunched(const std::wstring& loader_channel_id, @@ -70,5 +73,5 @@ void NaClBrokerHost::OnLoaderLaunched(const std::wstring& loader_channel_id, void NaClBrokerHost::StopBroker() { stopping_ = true; - Send(new NaClProcessMsg_StopBroker()); + process_->Send(new NaClProcessMsg_StopBroker()); } diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.h b/chrome/browser/nacl_host/nacl_broker_host_win.h index bcb3a44..368f462 100644 --- a/chrome/browser/nacl_host/nacl_broker_host_win.h +++ b/chrome/browser/nacl_host/nacl_broker_host_win.h @@ -7,9 +7,15 @@ #pragma once #include "base/basictypes.h" -#include "content/browser/browser_child_process_host.h" +#include "base/memory/scoped_ptr.h" +#include "base/process.h" +#include "content/public/browser/browser_child_process_host_delegate.h" -class NaClBrokerHost : public BrowserChildProcessHost { +namespace content { +class BrowserChildProcessHost; +} + +class NaClBrokerHost : public content::BrowserChildProcessHostDelegate { public: NaClBrokerHost(); ~NaClBrokerHost(); @@ -30,11 +36,13 @@ class NaClBrokerHost : public BrowserChildProcessHost { void OnLoaderLaunched(const std::wstring& loader_channel_id, base::ProcessHandle handle); - // BrowserChildProcessHost implementation: + // BrowserChildProcessHostDelegate implementation: virtual bool OnMessageReceived(const IPC::Message& msg); bool stopping_; + scoped_ptr<content::BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(NaClBrokerHost); }; diff --git a/chrome/browser/nacl_host/nacl_broker_service_win.cc b/chrome/browser/nacl_host/nacl_broker_service_win.cc index 7e93e3e..8b7bd90b 100644 --- a/chrome/browser/nacl_host/nacl_broker_service_win.cc +++ b/chrome/browser/nacl_host/nacl_broker_service_win.cc @@ -5,6 +5,9 @@ #include "chrome/browser/nacl_host/nacl_broker_service_win.h" #include "chrome/browser/nacl_host/nacl_process_host.h" +#include "content/public/browser/browser_child_process_host_iterator.h" + +using content::BrowserChildProcessHostIterator; NaClBrokerService* NaClBrokerService::GetInstance() { return Singleton<NaClBrokerService>::get(); @@ -62,9 +65,8 @@ void NaClBrokerService::OnLoaderDied() { } NaClBrokerHost* NaClBrokerService::GetBrokerHost() { - BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_NACL_BROKER); + BrowserChildProcessHostIterator iter(content::PROCESS_TYPE_NACL_BROKER); if (iter.Done()) return NULL; - NaClBrokerHost* broker_host = static_cast<NaClBrokerHost*>(*iter); - return broker_host; + return static_cast<NaClBrokerHost*>(iter.GetDelegate()); } diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index da2ae24..7d8ddd3 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -24,6 +24,8 @@ #include "chrome/common/nacl_messages.h" #include "chrome/common/render_messages.h" #include "chrome/browser/renderer_host/chrome_render_message_filter.h" +#include "content/public/browser/browser_child_process_host.h" +#include "content/public/browser/child_process_data.h" #include "content/public/common/child_process_host.h" #include "ipc/ipc_switches.h" #include "native_client/src/shared/imc/nacl_imc.h" @@ -35,6 +37,7 @@ #endif using content::BrowserThread; +using content::ChildProcessData; using content::ChildProcessHost; namespace { @@ -109,16 +112,17 @@ static bool RunningOnWOW64() { #endif NaClProcessHost::NaClProcessHost(const std::wstring& url) - : BrowserChildProcessHost(content::PROCESS_TYPE_NACL_LOADER), - reply_msg_(NULL), + : reply_msg_(NULL), internal_(new NaClInternal()), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { - SetName(WideToUTF16Hack(url)); + process_.reset(content::BrowserChildProcessHost::Create( + content::PROCESS_TYPE_NACL_LOADER, this)); + process_->SetName(WideToUTF16Hack(url)); } NaClProcessHost::~NaClProcessHost() { int exit_code; - GetChildTerminationStatus(&exit_code); + process_->GetTerminationStatus(&exit_code); std::string message = base::StringPrintf("NaCl process exited with status %i (0x%x)", exit_code, exit_code); @@ -234,7 +238,7 @@ bool NaClProcessHost::Launch( } bool NaClProcessHost::LaunchSelLdr() { - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -283,19 +287,19 @@ bool NaClProcessHost::LaunchSelLdr() { return NaClBrokerService::GetInstance()->LaunchLoader( this, ASCIIToWide(channel_id)); } else { - BrowserChildProcessHost::Launch(FilePath(), cmd_line); + process_->Launch(FilePath(), cmd_line); } #elif defined(OS_POSIX) - BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote - base::environment_vector(), - cmd_line); + process_->Launch(nacl_loader_prefix.empty(), // use_zygote + base::environment_vector(), + cmd_line); #endif return true; } void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { - SetHandle(handle); + process_->SetHandle(handle); OnProcessLaunched(); } @@ -469,10 +473,11 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { #endif } + const ChildProcessData& data = process_->GetData(); #if defined(OS_WIN) // Copy the process handle into the renderer process. if (!DuplicateHandle(base::GetCurrentProcessHandle(), - data().handle, + data.handle, chrome_render_message_filter_->peer_handle(), &nacl_process_handle, PROCESS_DUP_HANDLE, @@ -484,11 +489,11 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { } #else // We use pid as process handle on Posix - nacl_process_handle = data().handle; + nacl_process_handle = data.handle; #endif // Get the pid of the NaCl process - base::ProcessId nacl_process_id = base::GetProcId(data().handle); + base::ProcessId nacl_process_id = base::GetProcId(data.handle); ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); @@ -499,7 +504,7 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { std::vector<nacl::FileDescriptor> handles_for_sel_ldr; for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { - if (!SendHandleToSelLdr(data().handle, + if (!SendHandleToSelLdr(data.handle, internal_->sockets_for_sel_ldr[i], true, &handles_for_sel_ldr)) { delete this; @@ -508,8 +513,7 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { } // Send over the IRT file handle. We don't close our own copy! - if (!SendHandleToSelLdr( - data().handle, irt_file, false, &handles_for_sel_ldr)) { + if (!SendHandleToSelLdr(data.handle, irt_file, false, &handles_for_sel_ldr)) { delete this; return; } @@ -539,7 +543,7 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { handles_for_sel_ldr.push_back(memory_fd); #endif - Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); + process_->Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); internal_->sockets_for_sel_ldr.clear(); } diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index 0677801..56f0553 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -12,18 +12,23 @@ #include "base/file_util_proxy.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/process.h" #include "chrome/common/nacl_types.h" -#include "content/browser/browser_child_process_host.h" +#include "content/public/browser/browser_child_process_host_delegate.h" class ChromeRenderMessageFilter; +namespace content { +class BrowserChildProcessHost; +} + // Represents the browser side of the browser <--> NaCl communication // channel. There will be one NaClProcessHost per NaCl process // The browser is responsible for starting the NaCl process // when requested by the renderer. // After that, most of the communication is directly between NaCl plugin // running in the renderer and NaCl processes. -class NaClProcessHost : public BrowserChildProcessHost { +class NaClProcessHost : public content::BrowserChildProcessHostDelegate { public: explicit NaClProcessHost(const std::wstring& url); virtual ~NaClProcessHost(); @@ -39,10 +44,6 @@ class NaClProcessHost : public BrowserChildProcessHost { int socket_count, IPC::Message* reply_msg); - // BrowserChildProcessHost implementation: - virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; - virtual void OnProcessCrashed(int exit_code) OVERRIDE; - void OnProcessLaunchedByBroker(base::ProcessHandle handle); private: @@ -54,6 +55,9 @@ class NaClProcessHost : public BrowserChildProcessHost { bool LaunchSelLdr(); + // BrowserChildProcessHostDelegate implementation: + virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; + virtual void OnProcessCrashed(int exit_code) OVERRIDE; virtual void OnProcessLaunched() OVERRIDE; void IrtReady(); @@ -74,6 +78,8 @@ class NaClProcessHost : public BrowserChildProcessHost { base::WeakPtrFactory<NaClProcessHost> weak_factory_; + scoped_ptr<content::BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(NaClProcessHost); }; diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc index d47c0d8..5a8e571 100644 --- a/chrome/browser/notifications/desktop_notification_service.cc +++ b/chrome/browser/notifications/desktop_notification_service.cc @@ -28,7 +28,6 @@ #include "chrome/common/content_settings_pattern.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/site_instance.h" #include "content/browser/worker_host/worker_process_host.h" diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index 383c7ef..19cf9e8 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -41,9 +41,10 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" @@ -64,6 +65,7 @@ #include "ui/gfx/icon_util.h" #endif // defined(OS_WIN) +using content::BrowserChildProcessHostIterator; using content::BrowserThread; using content::WebContents; @@ -1068,11 +1070,11 @@ void TaskManagerChildProcessResourceProvider::AddToTaskManager( // The ChildProcessData::Iterator has to be used from the IO thread. void TaskManagerChildProcessResourceProvider::RetrieveChildProcessData() { std::vector<content::ChildProcessData> child_processes; - for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) { + for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { // Only add processes which are already started, since we need their handle. - if ((*iter)->data().handle == base::kNullProcessHandle) + if (iter.GetData().handle == base::kNullProcessHandle) continue; - child_processes.push_back((*iter)->data()); + child_processes.push_back(iter.GetData()); } // Now notify the UI thread that we have retrieved information about child // processes. diff --git a/chrome/browser/task_manager/task_manager_worker_resource_provider.cc b/chrome/browser/task_manager/task_manager_worker_resource_provider.cc index a3fccb6..5712732 100644 --- a/chrome/browser/task_manager/task_manager_worker_resource_provider.cc +++ b/chrome/browser/task_manager/task_manager_worker_resource_provider.cc @@ -11,7 +11,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/debugger/devtools_window.h" #include "chrome/browser/profiles/profile_manager.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/worker_host/worker_process_host.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" @@ -218,7 +217,7 @@ void TaskManagerWorkerResourceProvider::WorkerCreated( WorkerProcessHost* process, const WorkerProcessHost::WorkerInstance& instance) { TaskManagerSharedWorkerResource* resource = - new TaskManagerSharedWorkerResource(process->data(), + new TaskManagerSharedWorkerResource(process->GetData(), instance.worker_route_id(), instance.url(), instance.name()); BrowserThread::PostTask( @@ -233,7 +232,7 @@ void TaskManagerWorkerResourceProvider::WorkerDestroyed( BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind( &TaskManagerWorkerResourceProvider::NotifyWorkerDestroyed, - this, process->data().id, worker_route_id)); + this, process->GetData().id, worker_route_id)); } void TaskManagerWorkerResourceProvider::Observe( @@ -304,14 +303,12 @@ void TaskManagerWorkerResourceProvider::StartObservingWorkers() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); scoped_ptr<WorkerResourceListHolder> holder(new WorkerResourceListHolder); - BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - for (; !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - const WorkerProcessHost::Instances& instances = worker->instances(); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + const WorkerProcessHost::Instances& instances = (*iter)->instances(); for (WorkerProcessHost::Instances::const_iterator i = instances.begin(); i != instances.end(); ++i) { holder->resources()->push_back(new TaskManagerSharedWorkerResource( - (*iter)->data(), i->worker_route_id(), i->url(), i->name())); + iter.GetData(), i->worker_route_id(), i->url(), i->name())); } } diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index 79ecf8c..9631228 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm @@ -5,6 +5,7 @@ #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "base/bind.h" +#include "base/message_loop.h" #include "base/stl_util.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" diff --git a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc index 3643935..5ae03d6 100644 --- a/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc +++ b/chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/i18n/rtl.h" +#include "base/message_loop.h" #include "base/utf_string_conversions.h" #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_context_menu_model.h" diff --git a/chrome/browser/ui/intents/web_intents_model_unittest.cc b/chrome/browser/ui/intents/web_intents_model_unittest.cc index ee4f287..a2fbe2e 100644 --- a/chrome/browser/ui/intents/web_intents_model_unittest.cc +++ b/chrome/browser/ui/intents/web_intents_model_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/file_util.h" +#include "base/message_loop.h" #include "base/scoped_temp_dir.h" #include "base/synchronization/waitable_event.h" #include "base/utf_string_conversions.h" diff --git a/chrome/browser/ui/webui/options/chromeos/user_image_source.cc b/chrome/browser/ui/webui/options/chromeos/user_image_source.cc index 65d16d6..c5297df 100644 --- a/chrome/browser/ui/webui/options/chromeos/user_image_source.cc +++ b/chrome/browser/ui/webui/options/chromeos/user_image_source.cc @@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/options/chromeos/user_image_source.h" #include "base/memory/ref_counted_memory.h" +#include "base/message_loop.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/common/url_constants.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/ui/webui/options2/chromeos/user_image_source2.cc b/chrome/browser/ui/webui/options2/chromeos/user_image_source2.cc index 3b838ea..eae0385 100644 --- a/chrome/browser/ui/webui/options2/chromeos/user_image_source2.cc +++ b/chrome/browser/ui/webui/options2/chromeos/user_image_source2.cc @@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/options2/chromeos/user_image_source2.h" #include "base/memory/ref_counted_memory.h" +#include "base/message_loop.h" #include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/common/url_constants.h" #include "grit/theme_resources.h" diff --git a/chrome/browser/ui/webui/workers_ui.cc b/chrome/browser/ui/webui/workers_ui.cc index 5917d49..313a7e7 100644 --- a/chrome/browser/ui/webui/workers_ui.cc +++ b/chrome/browser/ui/webui/workers_ui.cc @@ -17,6 +17,7 @@ #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" #include "chrome/common/url_constants.h" #include "content/browser/worker_host/worker_process_host.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/devtools_agent_host_registry.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" @@ -30,6 +31,7 @@ #include "ui/base/resource/resource_bundle.h" using content::BrowserThread; +using content::ChildProcessData; using content::DevToolsAgentHost; using content::DevToolsAgentHostRegistry; using content::WebContents; @@ -51,15 +53,14 @@ static const char kPidField[] = "pid"; namespace { -DictionaryValue* BuildWorkerData( - WorkerProcessHost* process, +DictionaryValue* BuildWorkerData(const ChildProcessData& data, const WorkerProcessHost::WorkerInstance& instance) { DictionaryValue* worker_data = new DictionaryValue(); - worker_data->SetInteger(kWorkerProcessHostIdField, process->data().id); + worker_data->SetInteger(kWorkerProcessHostIdField, data.id); worker_data->SetInteger(kWorkerRouteIdField, instance.worker_route_id()); worker_data->SetString(kUrlField, instance.url().spec()); worker_data->SetString(kNameField, instance.name()); - worker_data->SetInteger(kPidField, base::GetProcId(process->data().handle)); + worker_data->SetInteger(kPidField, base::GetProcId(data.handle)); return worker_data; } @@ -94,13 +95,11 @@ void WorkersUIHTMLSource::StartDataRequest(const std::string& path, void WorkersUIHTMLSource::SendSharedWorkersData(int request_id) { ListValue workers_list; - BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - for (; !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - const WorkerProcessHost::Instances& instances = worker->instances(); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + const WorkerProcessHost::Instances& instances = iter->instances(); for (WorkerProcessHost::Instances::const_iterator i = instances.begin(); i != instances.end(); ++i) { - workers_list.Append(BuildWorkerData(worker, *i)); + workers_list.Append(BuildWorkerData(iter.GetData(), *i)); } } @@ -158,11 +157,9 @@ void WorkersDOMHandler::HandleOpenDevTools(const ListValue* args) { } static void TerminateWorker(int worker_process_id, int worker_route_id) { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - if (iter->data().id == worker_process_id) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - worker->TerminateWorker(worker_route_id); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter.GetData().id == worker_process_id) { + iter->TerminateWorker(worker_route_id); return; } } @@ -216,14 +213,15 @@ class WorkersUI::WorkerCreationDestructionListener const WorkerProcessHost::WorkerInstance& instance) OVERRIDE { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&WorkerCreationDestructionListener::NotifyWorkerCreated, - this, base::Owned(BuildWorkerData(process, instance)))); + base::Bind( + &WorkerCreationDestructionListener::NotifyWorkerCreated, + this, base::Owned(BuildWorkerData(process->GetData(), instance)))); } virtual void WorkerDestroyed( WorkerProcessHost* process, int worker_route_id) OVERRIDE { DictionaryValue* worker_data = new DictionaryValue(); - worker_data->SetInteger(kWorkerProcessHostIdField, process->data().id); + worker_data->SetInteger(kWorkerProcessHostIdField, process->GetData().id); worker_data->SetInteger(kWorkerRouteIdField, worker_route_id); BrowserThread::PostTask( diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc index 65a6de5..a93fdde 100644 --- a/chrome/browser/web_resource/web_resource_service.cc +++ b/chrome/browser/web_resource/web_resource_service.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/message_loop.h" #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/time.h" diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index 91f6627..e3a0000 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc @@ -152,10 +152,6 @@ FilePath ServiceUtilityProcessHost::GetUtilityProcessCmd() { return ChildProcessHost::GetChildPath(flags); } -bool ServiceUtilityProcessHost::CanShutdown() { - return true; -} - void ServiceUtilityProcessHost::OnChildDisconnected() { if (waiting_for_reply_) { // If we are yet to receive a reply then notify the client that the @@ -166,9 +162,6 @@ void ServiceUtilityProcessHost::OnChildDisconnected() { delete this; } -void ServiceUtilityProcessHost::ShutdownStarted() { -} - bool ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(ServiceUtilityProcessHost, message) diff --git a/chrome/service/service_utility_process_host.h b/chrome/service/service_utility_process_host.h index 0b91776..3fb3a45 100644 --- a/chrome/service/service_utility_process_host.h +++ b/chrome/service/service_utility_process_host.h @@ -108,9 +108,7 @@ class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate { virtual FilePath GetUtilityProcessCmd(); // ChildProcessHostDelegate implementation: - virtual bool CanShutdown() OVERRIDE; virtual void OnChildDisconnected() OVERRIDE; - virtual void ShutdownStarted() OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; private: diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc index 9bd3b21..fee30a2 100644 --- a/content/browser/browser_child_process_host.cc +++ b/content/browser/browser_child_process_host.cc @@ -20,6 +20,7 @@ #include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/notification_service.h" @@ -33,31 +34,48 @@ #include "base/bind.h" #endif +using content::BrowserChildProcessHostDelegate; using content::BrowserThread; +using content::ChildProcessData; using content::ChildProcessHost; using content::ChildProcessHostImpl; namespace { -typedef std::list<BrowserChildProcessHost*> BrowserChildProcessList; -static base::LazyInstance<BrowserChildProcessList> g_child_process_list = - LAZY_INSTANCE_INITIALIZER; +static base::LazyInstance<BrowserChildProcessHost::BrowserChildProcessList> + g_child_process_list = LAZY_INSTANCE_INITIALIZER; // Helper functions since the child process related notifications happen on the // UI thread. void ChildNotificationHelper(int notification_type, - const content::ChildProcessData& data) { + const ChildProcessData& data) { content::NotificationService::current()-> Notify(notification_type, content::NotificationService::AllSources(), - content::Details<const content::ChildProcessData>(&data)); + content::Details<const ChildProcessData>(&data)); } } // namespace +namespace content { + +BrowserChildProcessHost* BrowserChildProcessHost::Create( + ProcessType type, + BrowserChildProcessHostDelegate* delegate) { + return new ::BrowserChildProcessHost(type, delegate); +} + +} // namespace content + +BrowserChildProcessHost::BrowserChildProcessList* + BrowserChildProcessHost::GetIterator() { + return g_child_process_list.Pointer(); +} + BrowserChildProcessHost::BrowserChildProcessHost( - content::ProcessType type) + content::ProcessType type, + BrowserChildProcessHostDelegate* delegate) : data_(type), - ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), + delegate_(delegate), #if !defined(OS_WIN) ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), #endif @@ -77,6 +95,7 @@ BrowserChildProcessHost::~BrowserChildProcessHost() { // static void BrowserChildProcessHost::TerminateAll() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Make a copy since the BrowserChildProcessHost dtor mutates the original // list. BrowserChildProcessList copy = g_child_process_list.Get(); @@ -91,9 +110,10 @@ void BrowserChildProcessHost::Launch( const base::environment_vector& environ, #endif CommandLine* cmd_line) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); content::GetContentClient()->browser()->AppendExtraCommandLineSwitches( - cmd_line, data().id); + cmd_line, data_.id); child_process_.reset(new ChildProcessLauncher( #if defined(OS_WIN) @@ -101,13 +121,24 @@ void BrowserChildProcessHost::Launch( #elif defined(OS_POSIX) use_zygote, environ, - child_process_host()->TakeClientFileDescriptor(), + child_process_host_->TakeClientFileDescriptor(), #endif cmd_line, - &client_)); + this)); } -base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { +const ChildProcessData& BrowserChildProcessHost::GetData() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return data_; +} + +ChildProcessHost* BrowserChildProcessHost::GetHost() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return child_process_host_.get(); +} + +base::ProcessHandle BrowserChildProcessHost::GetHandle() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(child_process_.get()) << "Requesting a child process handle before launching."; DCHECK(child_process_->GetHandle()) @@ -116,20 +147,24 @@ base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { } void BrowserChildProcessHost::SetName(const string16& name) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); data_.name = name; } void BrowserChildProcessHost::SetHandle(base::ProcessHandle handle) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); data_.handle = handle; } void BrowserChildProcessHost::ForceShutdown() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); g_child_process_list.Get().remove(this); child_process_host_->ForceShutdown(); } void BrowserChildProcessHost::SetTerminateChildOnShutdown( - bool terminate_on_shutdown) { + bool terminate_on_shutdown) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); } @@ -140,23 +175,29 @@ void BrowserChildProcessHost::Notify(int type) { base::Bind(&ChildNotificationHelper, type, data_)); } -base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( +base::TerminationStatus BrowserChildProcessHost::GetTerminationStatus( int* exit_code) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!child_process_.get()) // If the delegate doesn't use Launch() helper. - return base::GetTerminationStatus(data().handle, exit_code); + return base::GetTerminationStatus(data_.handle, exit_code); return child_process_->GetChildTerminationStatus(exit_code); } bool BrowserChildProcessHost::OnMessageReceived(const IPC::Message& message) { - return false; + return delegate_->OnMessageReceived(message); } void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) { Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); + delegate_->OnChannelConnected(peer_pid); +} + +void BrowserChildProcessHost::OnChannelError() { + delegate_->OnChannelError(); } bool BrowserChildProcessHost::CanShutdown() { - return true; + return delegate_->CanShutdown(); } // Normally a ChildProcessHostDelegate deletes itself from this callback, but at @@ -167,21 +208,21 @@ bool BrowserChildProcessHost::CanShutdown() { // may be called twice: once from the actual channel error and once from // OnWaitableEventSignaled() or the delayed task. void BrowserChildProcessHost::OnChildDisconnected() { - DCHECK(data().handle != base::kNullProcessHandle); + DCHECK(data_.handle != base::kNullProcessHandle); int exit_code; - base::TerminationStatus status = GetChildTerminationStatus(&exit_code); + base::TerminationStatus status = GetTerminationStatus(&exit_code); switch (status) { case base::TERMINATION_STATUS_PROCESS_CRASHED: case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { - OnProcessCrashed(exit_code); + delegate_->OnProcessCrashed(exit_code); // Report that this child process crashed. Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED); UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", - data().type, + data_.type, content::PROCESS_TYPE_MAX); if (disconnect_was_alive_) { UMA_HISTOGRAM_ENUMERATION("ChildProcess.CrashedWasAlive", - data().type, + data_.type, content::PROCESS_TYPE_MAX); } break; @@ -189,11 +230,11 @@ void BrowserChildProcessHost::OnChildDisconnected() { case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { // Report that this child process was killed. UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed", - data().type, + data_.type, content::PROCESS_TYPE_MAX); if (disconnect_was_alive_) { UMA_HISTOGRAM_ENUMERATION("ChildProcess.KilledWasAlive", - data().type, + data_.type, content::PROCESS_TYPE_MAX); } break; @@ -203,14 +244,14 @@ void BrowserChildProcessHost::OnChildDisconnected() { // code. if (disconnect_was_alive_) { UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive", - data().type, + data_.type, content::PROCESS_TYPE_MAX); break; } disconnect_was_alive_ = true; #if defined(OS_WIN) child_watcher_.StartWatching( - new base::WaitableEvent(data().handle), this); + new base::WaitableEvent(data_.handle), this); #else // On non-Windows platforms, give the child process some time to die after // disconnecting the channel so that the exit code and termination status @@ -230,7 +271,7 @@ void BrowserChildProcessHost::OnChildDisconnected() { break; } UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", - data().type, + data_.type, content::PROCESS_TYPE_MAX); // Notify in the main loop of the disconnection. Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); @@ -265,50 +306,12 @@ void BrowserChildProcessHost::ShutdownStarted() { g_child_process_list.Get().remove(this); } -BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) - : host_(host) { -} -void BrowserChildProcessHost::ClientHook::OnProcessLaunched() { - if (!host_->child_process_->GetHandle()) { - delete host_; +void BrowserChildProcessHost::OnProcessLaunched() { + if (!child_process_->GetHandle()) { + delete this; return; } - host_->data_.handle = host_->child_process_->GetHandle(); - host_->OnProcessLaunched(); -} - -BrowserChildProcessHost::Iterator::Iterator() - : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << - "BrowserChildProcessHost::Iterator must be used on the IO thread."; - iterator_ = g_child_process_list.Get().begin(); -} - -BrowserChildProcessHost::Iterator::Iterator(content::ProcessType type) - : all_(false), type_(type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << - "BrowserChildProcessHost::Iterator must be used on the IO thread."; - iterator_ = g_child_process_list.Get().begin(); - if (!Done() && (*iterator_)->data().type != type_) - ++(*this); -} - -BrowserChildProcessHost* BrowserChildProcessHost::Iterator::operator++() { - do { - ++iterator_; - if (Done()) - break; - - if (!all_ && (*iterator_)->data().type != type_) - continue; - - return *iterator_; - } while (true); - - return NULL; -} - -bool BrowserChildProcessHost::Iterator::Done() { - return iterator_ == g_child_process_list.Get().end(); + data_.handle = child_process_->GetHandle(); + delegate_->OnProcessLaunched(); } diff --git a/content/browser/browser_child_process_host.h b/content/browser/browser_child_process_host.h index 3fac085..45d2a22 100644 --- a/content/browser/browser_child_process_host.h +++ b/content/browser/browser_child_process_host.h @@ -14,116 +14,52 @@ #include "base/process.h" #include "base/synchronization/waitable_event_watcher.h" #include "content/browser/child_process_launcher.h" -#include "content/common/content_export.h" +#include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/child_process_data.h" #include "content/public/common/child_process_host_delegate.h" -#include "ipc/ipc_message.h" - -namespace base { -class WaitableEvent; -} namespace content { -class ChildProcessHost; +class BrowserChildProcessHostIterator; } -// Plugins/workers and other child processes that live on the IO thread should -// derive from this class. -// -// [Browser]RenderProcessHost is the main exception that doesn't derive from -// this class. That project lives on the UI thread. +// Plugins/workers and other child processes that live on the IO thread use this +// class. RenderProcessHostImpl is the main exception that doesn't use this +/// class because it lives on the UI thread. class CONTENT_EXPORT BrowserChildProcessHost : + public NON_EXPORTED_BASE(content::BrowserChildProcessHost), public NON_EXPORTED_BASE(content::ChildProcessHostDelegate), public ChildProcessLauncher::Client, - public base::WaitableEventWatcher::Delegate, - public IPC::Message::Sender { + public base::WaitableEventWatcher::Delegate { public: + BrowserChildProcessHost(content::ProcessType type, + content::BrowserChildProcessHostDelegate* delegate); virtual ~BrowserChildProcessHost(); - virtual void OnWaitableEventSignaled( - base::WaitableEvent* waitable_event) OVERRIDE; - // Terminates all child processes and deletes each BrowserChildProcessHost // instance. static void TerminateAll(); - // The Iterator class allows iteration through either all child processes, or - // ones of a specific type, depending on which constructor is used. Note that - // this should be done from the IO thread and that the iterator should not be - // kept around as it may be invalidated on subsequent event processing in the - // event loop. - class CONTENT_EXPORT Iterator { - public: - Iterator(); - explicit Iterator(content::ProcessType type); - BrowserChildProcessHost* operator->() { return *iterator_; } - BrowserChildProcessHost* operator*() { return *iterator_; } - BrowserChildProcessHost* operator++(); - bool Done(); - - private: - bool all_; - content::ProcessType type_; - std::list<BrowserChildProcessHost*>::iterator iterator_; - }; - - // IPC::Message::Sender override + // BrowserChildProcessHost implementation: virtual bool Send(IPC::Message* message) OVERRIDE; - - const content::ChildProcessData& data() const { return data_; } - bool disconnect_was_alive() const { return disconnect_was_alive_; } - - protected: - explicit BrowserChildProcessHost(content::ProcessType type); - - // Derived classes call this to launch the child process asynchronously. - void Launch( + virtual void Launch( #if defined(OS_WIN) const FilePath& exposed_dir, #elif defined(OS_POSIX) bool use_zygote, const base::environment_vector& environ, #endif - CommandLine* cmd_line); - - // TODO(jam): below is what will be in the BrowserChildProcessHostDelegate - // interface. - - // ChildProcessLauncher::Client implementation. - virtual void OnProcessLaunched() OVERRIDE {} - - // Derived classes can override this to know if the process crashed. - // |exit_code| is the status returned when the process crashed (for - // posix, as returned from waitpid(), for Windows, as returned from - // GetExitCodeProcess()). - virtual void OnProcessCrashed(int exit_code) {} - - // Overrides from ChildProcessHostDelegate - virtual bool CanShutdown() OVERRIDE; - virtual void OnChildDisconnected() OVERRIDE; - virtual void ShutdownStarted() OVERRIDE; - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + CommandLine* cmd_line) OVERRIDE; + virtual const content::ChildProcessData& GetData() const OVERRIDE; + virtual content::ChildProcessHost* GetHost() const OVERRIDE; + virtual base::TerminationStatus GetTerminationStatus(int* exit_code) OVERRIDE; + virtual void SetName(const string16& name) OVERRIDE; + virtual void SetHandle(base::ProcessHandle handle) OVERRIDE; - // Returns the termination status of a child. |exit_code| is the - // status returned when the process exited (for posix, as returned - // from waitpid(), for Windows, as returned from - // GetExitCodeProcess()). |exit_code| may be NULL. - base::TerminationStatus GetChildTerminationStatus(int* exit_code); + bool disconnect_was_alive() const { return disconnect_was_alive_; } // Returns the handle of the child process. This can be called only after // OnProcessLaunched is called or it will be invalid and may crash. - base::ProcessHandle GetChildProcessHandle() const; - - // Sets the user-visible name of the process. - void SetName(const string16& name); - - // Set the handle of the process. BrowserChildProcessHost will do this when - // the Launch method is used to start the process. However if the owner - // of this object doesn't call Launch and starts the process in another way, - // they need to call this method so that the process handle is associated with - // this object. - void SetHandle(base::ProcessHandle handle); + base::ProcessHandle GetHandle() const; // Removes this host from the host list. Calls ChildProcessHost::ForceShutdown void ForceShutdown(); @@ -135,26 +71,35 @@ class CONTENT_EXPORT BrowserChildProcessHost : // Sends the given notification on the UI thread. void Notify(int type); - content::ChildProcessHost* child_process_host() const { - return child_process_host_.get(); + content::BrowserChildProcessHostDelegate* delegate() const { + return delegate_; } + typedef std::list<BrowserChildProcessHost*> BrowserChildProcessList; private: - // By using an internal class as the ChildProcessLauncher::Client, we can - // intercept OnProcessLaunched and do our own processing before - // calling the subclass' implementation. - class ClientHook : public ChildProcessLauncher::Client { - public: - explicit ClientHook(BrowserChildProcessHost* host); - virtual void OnProcessLaunched() OVERRIDE; - private: - BrowserChildProcessHost* host_; - }; + friend class content::BrowserChildProcessHostIterator; + + static BrowserChildProcessList* GetIterator(); + + // ChildProcessHostDelegate implementation: + virtual bool CanShutdown() OVERRIDE; + virtual void OnChildDisconnected() OVERRIDE; + virtual void ShutdownStarted() OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + virtual void OnChannelError() OVERRIDE; + + // ChildProcessLauncher::Client implementation. + virtual void OnProcessLaunched() OVERRIDE; + + // public base::WaitableEventWatcher::Delegate implementation: + virtual void OnWaitableEventSignaled( + base::WaitableEvent* waitable_event) OVERRIDE; content::ChildProcessData data_; + content::BrowserChildProcessHostDelegate* delegate_; scoped_ptr<content::ChildProcessHost> child_process_host_; - ClientHook client_; scoped_ptr<ChildProcessLauncher> child_process_; #if defined(OS_WIN) base::WaitableEventWatcher child_watcher_; diff --git a/content/browser/browser_process_sub_thread.cc b/content/browser/browser_process_sub_thread.cc index 35566f0..2b42da1 100644 --- a/content/browser/browser_process_sub_thread.cc +++ b/content/browser/browser_process_sub_thread.cc @@ -69,7 +69,7 @@ void BrowserProcessSubThread::IOThreadPreCleanUp() { // If any child processes are still running, terminate them and // and delete the BrowserChildProcessHost instances to release whatever // IO thread only resources they are referencing. - BrowserChildProcessHost::TerminateAll(); + ::BrowserChildProcessHost::TerminateAll(); } void BrowserProcessSubThread::IOThreadPostCleanUp() { diff --git a/content/browser/content_ipc_logging.cc b/content/browser/content_ipc_logging.cc index 4c9e8ea..45b7a2e 100644 --- a/content/browser/content_ipc_logging.cc +++ b/content/browser/content_ipc_logging.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "content/browser/browser_child_process_host.h" #include "content/common/child_process_messages.h" +#include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "ipc/ipc_logging.h" @@ -18,9 +19,9 @@ namespace content { void EnableIPCLoggingForChildProcesses(bool enabled) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - BrowserChildProcessHost::Iterator i; // default constr references a singleton + BrowserChildProcessHostIterator i; // default constr references a singleton while (!i.Done()) { - i->Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled)); + i.Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled)); ++i; } } diff --git a/content/browser/debugger/worker_devtools_manager.cc b/content/browser/debugger/worker_devtools_manager.cc index 2405fb7..217c946 100644 --- a/content/browser/debugger/worker_devtools_manager.cc +++ b/content/browser/debugger/worker_devtools_manager.cc @@ -15,6 +15,7 @@ #include "content/browser/worker_host/worker_service_impl.h" #include "content/common/devtools_messages.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/devtools_agent_host_registry.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -292,8 +293,7 @@ void WorkerDevToolsManager::WorkerCreated( instance.resource_context())) { worker->Send(new DevToolsAgentMsg_PauseWorkerContextOnStart( instance.worker_route_id())); - WorkerId new_worker_id( - worker->data().id, instance.worker_route_id()); + WorkerId new_worker_id(worker->GetData().id, instance.worker_route_id()); paused_workers_[new_worker_id] = it->old_worker_id; terminated_workers_.erase(it); return; @@ -305,12 +305,12 @@ void WorkerDevToolsManager::WorkerDestroyed( WorkerProcessHost* worker, int worker_route_id) { InspectedWorkersList::iterator it = FindInspectedWorker( - worker->data().id, + worker->GetData().id, worker_route_id); if (it == inspected_workers_.end()) return; - WorkerId worker_id(worker->data().id, worker_route_id); + WorkerId worker_id(worker->GetData().id, worker_route_id); terminated_workers_.push_back(TerminatedInspectedWorker( worker_id, it->worker_url, @@ -323,7 +323,7 @@ void WorkerDevToolsManager::WorkerDestroyed( void WorkerDevToolsManager::WorkerContextStarted(WorkerProcessHost* process, int worker_route_id) { - WorkerId new_worker_id(process->data().id, worker_route_id); + WorkerId new_worker_id(process->GetData().id, worker_route_id); PausedWorkers::iterator it = paused_workers_.find(new_worker_id); if (it == paused_workers_.end()) return; @@ -362,7 +362,7 @@ WorkerDevToolsManager::FindInspectedWorker( int host_id, int route_id) { InspectedWorkersList::iterator it = inspected_workers_.begin(); while (it != inspected_workers_.end()) { - if (it->host->data().id == host_id && it->route_id == route_id) + if (it->host->GetData().id == host_id && it->route_id == route_id) break; ++it; } @@ -370,10 +370,9 @@ WorkerDevToolsManager::FindInspectedWorker( } static WorkerProcessHost* FindWorkerProcess(int worker_process_id) { - BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - for (; !iter.Done(); ++iter) { - if (iter->data().id == worker_process_id) - return static_cast<WorkerProcessHost*>(*iter); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter.GetData().id == worker_process_id) + return *iter; } return NULL; } diff --git a/content/browser/debugger/worker_devtools_manager.h b/content/browser/debugger/worker_devtools_manager.h index 8ee9c1c..d2b2c023 100644 --- a/content/browser/debugger/worker_devtools_manager.h +++ b/content/browser/debugger/worker_devtools_manager.h @@ -7,6 +7,7 @@ #pragma once #include <list> +#include <map> #include <string> #include "base/basictypes.h" diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 1b15780..258c12a 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -15,6 +15,7 @@ #include "base/process_util.h" #include "base/string_piece.h" #include "base/threading/thread.h" +#include "content/browser/browser_child_process_host.h" #include "content/browser/gpu/gpu_data_manager.h" #include "content/browser/gpu/gpu_process_host_ui_shim.h" #include "content/browser/renderer_host/render_widget_host.h" @@ -160,12 +161,13 @@ class GpuMainThread : public base::Thread { DISALLOW_COPY_AND_ASSIGN(GpuMainThread); }; -static bool HostIsValid(GpuProcessHost* host) { +// static +bool GpuProcessHost::HostIsValid(GpuProcessHost* host) { if (!host) return false; // Check if the GPU process has died and the host is about to be destroyed. - if (host->disconnect_was_alive()) + if (host->process_->disconnect_was_alive()) return false; // The Gpu process is invalid if it's not using software, the card is @@ -245,8 +247,7 @@ GpuProcessHost* GpuProcessHost::FromID(int host_id) { } GpuProcessHost::GpuProcessHost(int host_id) - : BrowserChildProcessHost(content::PROCESS_TYPE_GPU), - host_id_(host_id), + : host_id_(host_id), gpu_process_(base::kNullProcessHandle), in_process_(false), software_rendering_(false) { @@ -269,6 +270,8 @@ GpuProcessHost::GpuProcessHost(int host_id) BrowserThread::UI, FROM_HERE, base::Bind(base::IgnoreResult(&GpuProcessHostUIShim::Create), host_id)); + + process_.reset(new BrowserChildProcessHost(content::PROCESS_TYPE_GPU, this)); } GpuProcessHost::~GpuProcessHost() { @@ -280,7 +283,7 @@ GpuProcessHost::~GpuProcessHost() { GPU_PROCESS_LIFETIME_EVENT_MAX); int exit_code; - base::TerminationStatus status = GetChildTerminationStatus(&exit_code); + base::TerminationStatus status = process_->GetTerminationStatus(&exit_code); UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationStatus", status, base::TERMINATION_STATUS_MAX_ENUM); @@ -311,7 +314,7 @@ GpuProcessHost::~GpuProcessHost() { } bool GpuProcessHost::Init() { - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -350,12 +353,12 @@ void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { bool GpuProcessHost::Send(IPC::Message* msg) { DCHECK(CalledOnValidThread()); - if (child_process_host()->IsChannelOpening()) { + if (process_->GetHost()->IsChannelOpening()) { queued_messages_.push(msg); return true; } - return BrowserChildProcessHost::Send(msg); + return process_->Send(msg); } bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { @@ -371,7 +374,6 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { } void GpuProcessHost::OnChannelConnected(int32 peer_pid) { - BrowserChildProcessHost::OnChannelConnected(peer_pid); while (!queued_messages_.empty()) { Send(queued_messages_.front()); queued_messages_.pop(); @@ -489,7 +491,7 @@ void GpuProcessHost::OnProcessLaunched() { // to such requests require that the GPU process handle be known. base::ProcessHandle child_handle = in_process_ ? - base::GetCurrentProcessHandle() : data().handle; + base::GetCurrentProcessHandle() : process_->GetData().handle; #if defined(OS_WIN) DuplicateHandle(base::GetCurrentProcessHandle(), @@ -510,7 +512,6 @@ void GpuProcessHost::OnProcessCrashed(int exit_code) { // The gpu process is too unstable to use. Disable it for current session. gpu_enabled_ = false; } - BrowserChildProcessHost::OnProcessCrashed(exit_code); } bool GpuProcessHost::software_rendering() { @@ -519,7 +520,7 @@ bool GpuProcessHost::software_rendering() { void GpuProcessHost::ForceShutdown() { g_hosts_by_id.Pointer()->Remove(host_id_); - BrowserChildProcessHost::ForceShutdown(); + process_->ForceShutdown(); } bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { @@ -589,7 +590,7 @@ bool GpuProcessHost::LaunchGpuProcess(const std::string& channel_id) { if (!gpu_launcher.empty()) cmd_line->PrependWrapper(gpu_launcher); - Launch( + process_->Launch( #if defined(OS_WIN) FilePath(), #elif defined(OS_POSIX) diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 29ec0df..51245d7 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -11,22 +11,22 @@ #include "base/callback.h" #include "base/memory/linked_ptr.h" +#include "base/process.h" #include "base/threading/non_thread_safe.h" -#include "content/browser/browser_child_process_host.h" #include "content/common/content_export.h" #include "content/common/gpu/gpu_process_launch_causes.h" +#include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/common/gpu_info.h" +#include "ipc/ipc_message.h" #include "ui/gfx/native_widget_types.h" +class GpuMainThread; struct GPUCreateCommandBufferConfig; -namespace IPC { -class Message; -} - -class GpuMainThread; +class BrowserChildProcessHost; -class GpuProcessHost : public BrowserChildProcessHost, +class GpuProcessHost : public content::BrowserChildProcessHostDelegate, + public IPC::Message::Sender, public base::NonThreadSafe { public: static bool gpu_enabled() { return gpu_enabled_; } @@ -52,12 +52,9 @@ class GpuProcessHost : public BrowserChildProcessHost, static GpuProcessHost* FromID(int host_id); int host_id() const { return host_id_; } + // IPC::Message::Sender implementation: virtual bool Send(IPC::Message* msg) OVERRIDE; - // ChildProcessHost implementation. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; - typedef base::Callback<void(const IPC::ChannelHandle&, base::ProcessHandle, const content::GPUInfo&)> @@ -86,6 +83,8 @@ class GpuProcessHost : public BrowserChildProcessHost, void ForceShutdown(); private: + static bool HostIsValid(GpuProcessHost* host); + GpuProcessHost(int host_id); virtual ~GpuProcessHost(); @@ -94,6 +93,9 @@ class GpuProcessHost : public BrowserChildProcessHost, // Post an IPC message to the UI shim's message handler on the UI thread. void RouteOnUIThread(const IPC::Message& message); + // BrowserChildProcessHostDelegate implementation. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnProcessLaunched() OVERRIDE; virtual void OnProcessCrashed(int exit_code) OVERRIDE; @@ -155,6 +157,8 @@ class GpuProcessHost : public BrowserChildProcessHost, // existing tabs, just the future ones. CONTENT_EXPORT static bool gpu_enabled_; + scoped_ptr<BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(GpuProcessHost); }; diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index cd8fb88..d15ffbd 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -21,6 +21,7 @@ #include "base/path_service.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "content/browser/browser_child_process_host.h" #include "content/browser/plugin_service_impl.h" #include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" @@ -36,6 +37,7 @@ #include "ui/gfx/native_widget_types.h" using content::BrowserThread; +using content::ChildProcessData; using content::ChildProcessHost; #if defined(USE_X11) @@ -91,7 +93,7 @@ void PluginProcessHost::OnReparentPluginWindow(HWND window, HWND parent) { // Reparent only from the plugin process to our process. DWORD process_id = 0; ::GetWindowThreadProcessId(window, &process_id); - if (process_id != ::GetProcessId(GetChildProcessHandle())) + if (process_id != ::GetProcessId(process_->GetHandle())) return; ::GetWindowThreadProcessId(parent, &process_id); if (process_id != ::GetCurrentProcessId()) @@ -114,11 +116,12 @@ void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, #endif // defined(TOOLKIT_USES_GTK) PluginProcessHost::PluginProcessHost() - : BrowserChildProcessHost(content::PROCESS_TYPE_PLUGIN) #if defined(OS_MACOSX) - , plugin_cursor_visible_(true) + : plugin_cursor_visible_(true) #endif { + process_.reset(new BrowserChildProcessHost( + content::PROCESS_TYPE_PLUGIN, this)); } PluginProcessHost::~PluginProcessHost() { @@ -164,11 +167,15 @@ PluginProcessHost::~PluginProcessHost() { CancelRequests(); } +bool PluginProcessHost::Send(IPC::Message* message) { + return process_->Send(message); +} + bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { info_ = info; - SetName(info_.name); + process_->SetName(info_.name); - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -258,7 +265,7 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { #endif #endif - Launch( + process_->Launch( #if defined(OS_WIN) FilePath(), #elif defined(OS_POSIX) @@ -271,7 +278,7 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { // called on the plugin. The plugin process exits when it receives the // OnChannelError notification indicating that the browser plugin channel has // been destroyed. - SetTerminateChildOnShutdown(false); + process_->SetTerminateChildOnShutdown(false); content::GetContentClient()->browser()->PluginProcessHostCreated(this); @@ -281,11 +288,11 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { void PluginProcessHost::ForceShutdown() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown()); - BrowserChildProcessHost::ForceShutdown(); + process_->ForceShutdown(); } void PluginProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { - child_process_host()->AddFilter(filter); + process_->GetHost()->AddFilter(filter); } bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { @@ -320,7 +327,6 @@ bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { } void PluginProcessHost::OnChannelConnected(int32 peer_pid) { - BrowserChildProcessHost::OnChannelConnected(peer_pid); for (size_t i = 0; i < pending_requests_.size(); ++i) { RequestPluginChannel(pending_requests_[i]); } @@ -352,9 +358,8 @@ void PluginProcessHost::CancelRequests() { // static void PluginProcessHost::CancelPendingRequestsForResourceContext( const content::ResourceContext* context) { - for (BrowserChildProcessHost::Iterator host_it(content::PROCESS_TYPE_PLUGIN); - !host_it.Done(); ++host_it) { - PluginProcessHost* host = static_cast<PluginProcessHost*>(*host_it); + for (PluginProcessHostIterator host_it; !host_it.Done(); ++host_it) { + PluginProcessHost* host = *host_it; for (size_t i = 0; i < host->pending_requests_.size(); ++i) { if (&host->pending_requests_[i]->GetResourceContext() == context) { host->pending_requests_[i]->OnError(); @@ -366,9 +371,9 @@ void PluginProcessHost::CancelPendingRequestsForResourceContext( } void PluginProcessHost::OpenChannelToPlugin(Client* client) { - Notify(content::NOTIFICATION_CHILD_INSTANCE_CREATED); + process_->Notify(content::NOTIFICATION_CHILD_INSTANCE_CREATED); client->SetPluginInfo(info_); - if (child_process_host()->IsChannelOpening()) { + if (process_->GetHost()->IsChannelOpening()) { // The channel is already in the process of being opened. Put // this "open channel" request into a queue of requests that will // be run once the channel is open. diff --git a/content/browser/plugin_process_host.h b/content/browser/plugin_process_host.h index 2fabe64..b5e8dff 100644 --- a/content/browser/plugin_process_host.h +++ b/content/browser/plugin_process_host.h @@ -14,13 +14,17 @@ #include <vector> #include "base/basictypes.h" +#include "base/compiler_specific.h" #include "base/memory/ref_counted.h" -#include "content/browser/browser_child_process_host.h" #include "content/common/content_export.h" +#include "content/public/browser/browser_child_process_host_delegate.h" +#include "content/public/browser/browser_child_process_host_iterator.h" #include "ipc/ipc_channel_proxy.h" #include "webkit/plugins/webplugininfo.h" #include "ui/gfx/native_widget_types.h" +class BrowserChildProcessHost; + namespace content { class ResourceContext; } @@ -41,7 +45,9 @@ struct ChannelHandle; // 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 CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHost { +class CONTENT_EXPORT PluginProcessHost + : public NON_EXPORTED_BASE(content::BrowserChildProcessHostDelegate), + public IPC::Message::Sender { public: class Client { public: @@ -65,6 +71,9 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHost { PluginProcessHost(); virtual ~PluginProcessHost(); + // IPC::Message::Sender implementation: + virtual bool Send(IPC::Message* message) OVERRIDE; + // Initialize the new plugin process, returning true on success. This must // be called before the object can be used. bool Init(const webkit::WebPluginInfo& info); @@ -169,7 +178,17 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHost { bool plugin_cursor_visible_; #endif + scoped_ptr<BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(PluginProcessHost); }; +class PluginProcessHostIterator + : public content::BrowserChildProcessHostTypeIterator<PluginProcessHost> { + public: + PluginProcessHostIterator() + : content::BrowserChildProcessHostTypeIterator<PluginProcessHost>( + content::PROCESS_TYPE_PLUGIN) {} +}; + #endif // CONTENT_BROWSER_PLUGIN_PROCESS_HOST_H_ diff --git a/content/browser/plugin_process_host_mac.cc b/content/browser/plugin_process_host_mac.cc index 91314b1..883d301 100644 --- a/content/browser/plugin_process_host_mac.cc +++ b/content/browser/plugin_process_host_mac.cc @@ -11,9 +11,12 @@ #include "base/bind.h" #include "base/logging.h" #include "base/mac/mac_util.h" +#include "base/process_util.h" +#include "content/browser/browser_child_process_host.h" #include "content/browser/plugin_process_host.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_data.h" #include "ui/gfx/rect.h" using content::BrowserThread; @@ -75,7 +78,8 @@ void PluginProcessHost::OnPluginHideWindow(uint32 window_id, if (plugin_fullscreen_windows_set_.find(window_id) != plugin_fullscreen_windows_set_.end()) { plugin_fullscreen_windows_set_.erase(window_id); - pid_t plugin_pid = browser_needs_activation ? -1 : data().handle; + pid_t plugin_pid = + browser_needs_activation ? -1 : process_->GetData().handle; browser_needs_activation = false; BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(ReleasePluginFullScreen, plugin_pid)); @@ -96,7 +100,7 @@ void PluginProcessHost::OnAppActivation() { if (!plugin_modal_windows_set_.empty()) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(base::mac::ActivateProcess, data().handle)); + base::Bind(base::mac::ActivateProcess, process_->GetData().handle)); } } diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index 84734d5f..cdb4db9 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -82,12 +82,8 @@ void WillLoadPluginsCallback() { static void NotifyPluginsOfActivation() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - for (BrowserChildProcessHost::Iterator iter( - content::PROCESS_TYPE_PLUGIN); - !iter.Done(); ++iter) { - PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); - plugin->OnAppActivation(); - } + for (PluginProcessHostIterator iter; !iter.Done(); ++iter) + iter->OnAppActivation(); } #endif #if defined(OS_POSIX) && !defined(OS_OPENBSD) @@ -231,13 +227,9 @@ void PluginServiceImpl::StartWatchingPlugins() { PluginProcessHost* PluginServiceImpl::FindNpapiPluginProcess( const FilePath& plugin_path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_PLUGIN); - !iter.Done(); ++iter) { - PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); - if (plugin->info().path == plugin_path) - return plugin; + for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter->info().path == plugin_path) + return *iter; } return NULL; @@ -245,15 +237,9 @@ PluginProcessHost* PluginServiceImpl::FindNpapiPluginProcess( PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess( const FilePath& plugin_path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - for (BrowserChildProcessHost::Iterator iter( - content::PROCESS_TYPE_PPAPI_PLUGIN); - !iter.Done(); ++iter) { - PpapiPluginProcessHost* plugin = - static_cast<PpapiPluginProcessHost*>(*iter); - if (plugin->plugin_path() == plugin_path) - return plugin; + for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter->plugin_path() == plugin_path) + return *iter; } return NULL; @@ -261,15 +247,9 @@ PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess( PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess( const FilePath& broker_path) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - for (BrowserChildProcessHost::Iterator iter( - content::PROCESS_TYPE_PPAPI_BROKER); - !iter.Done(); ++iter) { - PpapiPluginProcessHost* broker = - static_cast<PpapiPluginProcessHost*>(*iter); - if (broker->plugin_path() == broker_path) - return broker; + for (PpapiBrokerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter->plugin_path() == broker_path) + return *iter; } return NULL; diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index 96b5029..9ca0019 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc @@ -9,6 +9,7 @@ #include "base/file_path.h" #include "base/process_util.h" #include "base/utf_string_conversions.h" +#include "content/browser/browser_child_process_host.h" #include "content/browser/plugin_service_impl.h" #include "content/browser/renderer_host/render_message_filter.h" #include "content/common/child_process_host_impl.h" @@ -87,8 +88,12 @@ PpapiPluginProcessHost* PpapiPluginProcessHost::CreateBrokerHost( return NULL; } +bool PpapiPluginProcessHost::Send(IPC::Message* message) { + return process_->Send(message); +} + void PpapiPluginProcessHost::OpenChannelToPlugin(Client* client) { - if (child_process_host()->IsChannelOpening()) { + if (process_->GetHost()->IsChannelOpening()) { // The channel is already in the process of being opened. Put // this "open channel" request into a queue of requests that will // be run once the channel is open. @@ -101,29 +106,31 @@ void PpapiPluginProcessHost::OpenChannelToPlugin(Client* client) { } PpapiPluginProcessHost::PpapiPluginProcessHost(net::HostResolver* host_resolver) - : BrowserChildProcessHost(content::PROCESS_TYPE_PPAPI_PLUGIN), - filter_(new PepperMessageFilter(host_resolver)), + : filter_(new PepperMessageFilter(host_resolver)), network_observer_(new PluginNetworkObserver(this)), is_broker_(false), process_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()) { - child_process_host()->AddFilter(filter_.get()); + process_.reset(new BrowserChildProcessHost( + content::PROCESS_TYPE_PPAPI_PLUGIN, this)); + process_->GetHost()->AddFilter(filter_.get()); } PpapiPluginProcessHost::PpapiPluginProcessHost() - : BrowserChildProcessHost(content::PROCESS_TYPE_PPAPI_BROKER), - is_broker_(true), + : is_broker_(true), process_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()) { + process_.reset(new BrowserChildProcessHost( + content::PROCESS_TYPE_PPAPI_BROKER, this)); } bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) { plugin_path_ = info.path; if (info.name.empty()) { - SetName(plugin_path_.BaseName().LossyDisplayName()); + process_->SetName(plugin_path_.BaseName().LossyDisplayName()); } else { - SetName(UTF8ToUTF16(info.name)); + process_->SetName(UTF8ToUTF16(info.name)); } - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -176,7 +183,7 @@ bool PpapiPluginProcessHost::Init(const content::PepperPluginInfo& info) { #if defined(OS_POSIX) bool use_zygote = !is_broker_ && plugin_launcher.empty() && info.is_sandboxed; #endif // OS_POSIX - Launch( + process_->Launch( #if defined(OS_WIN) FilePath(), #elif defined(OS_POSIX) @@ -219,7 +226,6 @@ bool PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) { // Called when the browser <--> plugin channel has been established. void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) { - BrowserChildProcessHost::OnChannelConnected(peer_pid); // This will actually load the plugin. Errors will actually not be reported // back at this point. Instead, the plugin will fail to establish the // connections when we request them on behalf of the renderer(s). @@ -271,7 +277,7 @@ void PpapiPluginProcessHost::OnRendererPluginChannelCreated( sent_requests_.pop(); // Prepare the handle to send to the renderer. - base::ProcessHandle plugin_process = GetChildProcessHandle(); + base::ProcessHandle plugin_process = process_->GetHandle(); #if defined(OS_WIN) base::ProcessHandle renderer_process; int renderer_id; diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h index f92aa1d..0a37360 100644 --- a/content/browser/ppapi_plugin_process_host.h +++ b/content/browser/ppapi_plugin_process_host.h @@ -12,8 +12,12 @@ #include "base/file_path.h" #include "base/memory/scoped_ptr.h" #include "base/memory/ref_counted.h" -#include "content/browser/browser_child_process_host.h" #include "content/browser/renderer_host/pepper_message_filter.h" +#include "content/public/browser/browser_child_process_host_delegate.h" +#include "content/public/browser/browser_child_process_host_iterator.h" +#include "ipc/ipc_message.h" + +class BrowserChildProcessHost; namespace content { struct PepperPluginInfo; @@ -26,8 +30,8 @@ class HostResolver; // Process host for PPAPI plugin and broker processes. // When used for the broker, interpret all references to "plugin" with "broker". -class PpapiPluginProcessHost - : public BrowserChildProcessHost { +class PpapiPluginProcessHost : public content::BrowserChildProcessHostDelegate, + public IPC::Message::Sender { public: class Client { public: @@ -60,6 +64,9 @@ class PpapiPluginProcessHost static PpapiPluginProcessHost* CreateBrokerHost( const content::PepperPluginInfo& info); + // IPC::Message::Sender implementation: + virtual bool Send(IPC::Message* message) OVERRIDE; + // Opens a new channel to the plugin. The client will be notified when the // channel is ready or if there's an error. void OpenChannelToPlugin(Client* client); @@ -115,8 +122,28 @@ class PpapiPluginProcessHost // The unique id created for the process. int process_id_; + scoped_ptr<BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(PpapiPluginProcessHost); }; +class PpapiPluginProcessHostIterator + : public content::BrowserChildProcessHostTypeIterator< + PpapiPluginProcessHost> { + public: + PpapiPluginProcessHostIterator() + : content::BrowserChildProcessHostTypeIterator< + PpapiPluginProcessHost>(content::PROCESS_TYPE_PPAPI_PLUGIN) {} +}; + +class PpapiBrokerProcessHostIterator + : public content::BrowserChildProcessHostTypeIterator< + PpapiPluginProcessHost> { + public: + PpapiBrokerProcessHostIterator() + : content::BrowserChildProcessHostTypeIterator< + PpapiPluginProcessHost>(content::PROCESS_TYPE_PPAPI_BROKER) {} +}; + #endif // CONTENT_BROWSER_PPAPI_PLUGIN_PROCESS_HOST_H_ diff --git a/content/browser/profiler_controller_impl.cc b/content/browser/profiler_controller_impl.cc index 4b55357..1954da8 100644 --- a/content/browser/profiler_controller_impl.cc +++ b/content/browser/profiler_controller_impl.cc @@ -6,13 +6,15 @@ #include "base/bind.h" #include "base/values.h" -#include "content/browser/browser_child_process_host.h" #include "content/common/child_process_messages.h" +#include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/profiler_subscriber.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/process_type.h" +using content::BrowserChildProcessHostIterator; using content::BrowserThread; namespace content { @@ -73,13 +75,12 @@ void ProfilerControllerImpl::GetProfilerDataFromChildProcesses( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); int pending_processes = 0; - for (BrowserChildProcessHost::Iterator child_process_host; - !child_process_host.Done(); ++child_process_host) { + for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) { const std::string process_type = - content::GetProcessTypeNameInEnglish(child_process_host->data().type); + content::GetProcessTypeNameInEnglish(iter.GetData().type); ++pending_processes; - if (!child_process_host->Send(new ChildProcessMsg_GetChildProfilerData( - sequence_number, process_type))) { + if (!iter.Send(new ChildProcessMsg_GetChildProfilerData( + sequence_number, process_type))) { --pending_processes; } } @@ -123,10 +124,8 @@ void ProfilerControllerImpl::GetProfilerData(int sequence_number) { void ProfilerControllerImpl::SetProfilerStatusInChildProcesses(bool enable) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - for (BrowserChildProcessHost::Iterator child_process_host; - !child_process_host.Done(); ++child_process_host) { - child_process_host->Send(new ChildProcessMsg_SetProfilerStatus(enable)); - } + for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) + iter.Send(new ChildProcessMsg_SetProfilerStatus(enable)); } void ProfilerControllerImpl::SetProfilerStatus(bool enable) { diff --git a/content/browser/renderer_host/gpu_message_filter.cc b/content/browser/renderer_host/gpu_message_filter.cc index 14b3b50..efb5374 100644 --- a/content/browser/renderer_host/gpu_message_filter.cc +++ b/content/browser/renderer_host/gpu_message_filter.cc @@ -9,6 +9,7 @@ #include "content/browser/renderer_host/gpu_message_filter.h" #include "base/bind.h" +#include "base/process_util.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/gpu/gpu_surface_tracker.h" #include "content/browser/renderer_host/render_widget_helper.h" diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 87866b2..706211e 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -32,6 +32,7 @@ #include "content/common/plugin_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/notification_service.h" @@ -128,15 +129,13 @@ void NotifyPluginProcessHostHelper(HWND window, HWND parent, int tries) { DWORD plugin_process_id; bool found_starting_plugin_process = false; GetWindowThreadProcessId(window, &plugin_process_id); - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_PLUGIN); - !iter.Done(); ++iter) { - PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); - if (!plugin->data().handle) { + for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { + if (!iter.GetData().handle) { found_starting_plugin_process = true; continue; } - if (base::GetProcId(plugin->data().handle) == plugin_process_id) { - plugin->AddWindow(parent); + if (base::GetProcId(iter.GetData().handle) == plugin_process_id) { + iter->AddWindow(parent); return; } } diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index 68db20a..2c225af 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc @@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/message_loop.h" #include "base/utf_string_conversions.h" +#include "content/browser/browser_child_process_host.h" #include "content/common/child_process_host_impl.h" #include "content/common/utility_messages.h" #include "content/public/browser/content_browser_client.h" @@ -36,8 +37,7 @@ bool UtilityProcessHost::Client::OnMessageReceived( UtilityProcessHost::UtilityProcessHost(Client* client, BrowserThread::ID client_thread_id) - : BrowserChildProcessHost(content::PROCESS_TYPE_UTILITY), - client_(client), + : client_(client), client_thread_id_(client_thread_id), is_batch_mode_(false), no_sandbox_(false), @@ -48,6 +48,8 @@ UtilityProcessHost::UtilityProcessHost(Client* client, #endif use_linux_zygote_(false), started_(false) { + process_.reset(new BrowserChildProcessHost( + content::PROCESS_TYPE_UTILITY, this)); } UtilityProcessHost::~UtilityProcessHost() { @@ -58,7 +60,7 @@ bool UtilityProcessHost::Send(IPC::Message* message) { if (!StartProcess()) return false; - return BrowserChildProcessHost::Send(message); + return process_->Send(message); } bool UtilityProcessHost::StartBatchMode() { @@ -87,9 +89,9 @@ bool UtilityProcessHost::StartProcess() { return true; // Name must be set or metrics_service will crash in any test which // launches a UtilityProcessHost. - SetName(ASCIIToUTF16("utility process")); + process_->SetName(ASCIIToUTF16("utility process")); - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -136,7 +138,7 @@ bool UtilityProcessHost::StartProcess() { use_zygote = !no_sandbox_ && use_linux_zygote_; #endif - Launch( + process_->Launch( #if defined(OS_WIN) exposed_dir_, #elif defined(OS_POSIX) diff --git a/content/browser/utility_process_host.h b/content/browser/utility_process_host.h index 1481d44..18951d7 100644 --- a/content/browser/utility_process_host.h +++ b/content/browser/utility_process_host.h @@ -12,9 +12,12 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/process_util.h" -#include "content/browser/browser_child_process_host.h" #include "content/common/content_export.h" +#include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/browser/browser_thread.h" +#include "ipc/ipc_message.h" + +class BrowserChildProcessHost; // This class acts as the browser-side host to a utility child process. A // utility process is a short-lived sandboxed process that is created to run @@ -23,7 +26,9 @@ // If you need multiple batches of work to be done in the sandboxed process, // use StartBatchMode(), then multiple calls to StartFooBar(p), // then finish with EndBatchMode(). -class CONTENT_EXPORT UtilityProcessHost : public BrowserChildProcessHost { +class CONTENT_EXPORT UtilityProcessHost + : public NON_EXPORTED_BASE(content::BrowserChildProcessHostDelegate), + public IPC::Message::Sender { public: // An interface to be implemented by consumers of the utility process to // get results back. All functions are called on the thread passed along @@ -53,7 +58,7 @@ class CONTENT_EXPORT UtilityProcessHost : public BrowserChildProcessHost { content::BrowserThread::ID client_thread_id); virtual ~UtilityProcessHost(); - // BrowserChildProcessHost override + // IPC::Message::Sender implementation: virtual bool Send(IPC::Message* message) OVERRIDE; // Starts utility process in batch mode. Caller must call EndBatchMode() @@ -80,10 +85,8 @@ class CONTENT_EXPORT UtilityProcessHost : public BrowserChildProcessHost { // has already been started via StartBatchMode(). bool StartProcess(); - // IPC messages: - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - // BrowserChildProcessHost: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; virtual void OnProcessCrashed(int exit_code) OVERRIDE; // A pointer to our client interface, who will be informed of progress. @@ -112,6 +115,8 @@ class CONTENT_EXPORT UtilityProcessHost : public BrowserChildProcessHost { bool started_; + scoped_ptr<BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(UtilityProcessHost); }; diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc index 875511d..11b3464 100644 --- a/content/browser/worker_host/worker_process_host.cc +++ b/content/browser/worker_host/worker_process_host.cc @@ -16,6 +16,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "content/browser/appcache/appcache_dispatcher_host.h" +#include "content/browser/browser_child_process_host.h" #include "content/browser/child_process_security_policy.h" #include "content/browser/debugger/worker_devtools_message_filter.h" #include "content/browser/file_system/file_system_dispatcher_host.h" @@ -48,6 +49,7 @@ #include "webkit/glue/resource_type.h" using content::BrowserThread; +using content::ChildProcessData; using content::ChildProcessHost; using content::UserMetricsAction; using content::WorkerServiceImpl; @@ -86,10 +88,11 @@ void WorkerCrashCallback(int render_process_unique_id, int render_view_id) { WorkerProcessHost::WorkerProcessHost( const content::ResourceContext* resource_context) - : BrowserChildProcessHost(content::PROCESS_TYPE_WORKER), - resource_context_(resource_context) { + : resource_context_(resource_context) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(resource_context); + process_.reset(new BrowserChildProcessHost( + content::PROCESS_TYPE_WORKER, this)); } WorkerProcessHost::~WorkerProcessHost() { @@ -108,11 +111,15 @@ WorkerProcessHost::~WorkerProcessHost() { this, i->worker_route_id()); } - ChildProcessSecurityPolicy::GetInstance()->Remove(data().id); + ChildProcessSecurityPolicy::GetInstance()->Remove(process_->GetData().id); +} + +bool WorkerProcessHost::Send(IPC::Message* message) { + return process_->Send(message); } bool WorkerProcessHost::Init(int render_process_id) { - std::string channel_id = child_process_host()->CreateChannel(); + std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) return false; @@ -175,7 +182,7 @@ bool WorkerProcessHost::Init(int render_process_id) { } #endif - Launch( + process_->Launch( #if defined(OS_WIN) FilePath(), #elif defined(OS_POSIX) @@ -185,7 +192,7 @@ bool WorkerProcessHost::Init(int render_process_id) { cmd_line); ChildProcessSecurityPolicy::GetInstance()->AddWorker( - data().id, render_process_id); + process_->GetData().id, render_process_id); if (!CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableFileSystem)) { // Grant most file permissions to this worker. @@ -194,7 +201,7 @@ bool WorkerProcessHost::Init(int render_process_id) { // requests them. // This is for the filesystem sandbox. ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( - data().id, resource_context_->file_system_context()-> + process_->GetData().id, resource_context_->file_system_context()-> sandbox_provider()->new_base_path(), base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_CREATE | @@ -211,7 +218,7 @@ bool WorkerProcessHost::Init(int render_process_id) { // This is so that we can read and move stuff out of the old filesystem // sandbox. ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( - data().id, resource_context_->file_system_context()-> + process_->GetData().id, resource_context_->file_system_context()-> sandbox_provider()->old_base_path(), base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_WRITE_ATTRIBUTES | @@ -219,7 +226,7 @@ bool WorkerProcessHost::Init(int render_process_id) { // This is so that we can rename the old sandbox out of the way so that // we know we've taken care of it. ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( - data().id, resource_context_->file_system_context()-> + process_->GetData().id, resource_context_->file_system_context()-> sandbox_provider()->renamed_old_base_path(), base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE); @@ -236,37 +243,38 @@ void WorkerProcessHost::CreateMessageFilters(int render_process_id) { resource_context_->request_context(); ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( - data().id, content::PROCESS_TYPE_WORKER, resource_context_, + process_->GetData().id, content::PROCESS_TYPE_WORKER, resource_context_, new URLRequestContextSelector(request_context)); - child_process_host()->AddFilter(resource_message_filter); + process_->GetHost()->AddFilter(resource_message_filter); worker_message_filter_ = new WorkerMessageFilter( render_process_id, resource_context_, base::Bind(&WorkerServiceImpl::next_worker_route_id, base::Unretained(WorkerServiceImpl::GetInstance()))); - child_process_host()->AddFilter(worker_message_filter_); - child_process_host()->AddFilter(new AppCacheDispatcherHost( - resource_context_->appcache_service(), data().id)); - child_process_host()->AddFilter(new FileSystemDispatcherHost( + process_->GetHost()->AddFilter(worker_message_filter_); + process_->GetHost()->AddFilter(new AppCacheDispatcherHost( + resource_context_->appcache_service(), process_->GetData().id)); + process_->GetHost()->AddFilter(new FileSystemDispatcherHost( request_context, resource_context_->file_system_context())); - child_process_host()->AddFilter(new FileUtilitiesMessageFilter(data().id)); - child_process_host()->AddFilter(new BlobMessageFilter( - data().id, resource_context_->blob_storage_context())); - child_process_host()->AddFilter(new MimeRegistryMessageFilter()); - child_process_host()->AddFilter(new DatabaseMessageFilter( + process_->GetHost()->AddFilter(new FileUtilitiesMessageFilter( + process_->GetData().id)); + process_->GetHost()->AddFilter(new BlobMessageFilter( + process_->GetData().id, resource_context_->blob_storage_context())); + process_->GetHost()->AddFilter(new MimeRegistryMessageFilter()); + process_->GetHost()->AddFilter(new DatabaseMessageFilter( resource_context_->database_tracker())); SocketStreamDispatcherHost* socket_stream_dispatcher_host = new SocketStreamDispatcherHost( new URLRequestContextSelector(request_context), resource_context_); - child_process_host()->AddFilter(socket_stream_dispatcher_host); - child_process_host()->AddFilter( - new content::WorkerDevToolsMessageFilter(data().id)); + process_->GetHost()->AddFilter(socket_stream_dispatcher_host); + process_->GetHost()->AddFilter( + new content::WorkerDevToolsMessageFilter(process_->GetData().id)); } void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { ChildProcessSecurityPolicy::GetInstance()->GrantRequestURL( - data().id, instance.url()); + process_->GetData().id, instance.url()); instances_.push_back(instance); @@ -320,7 +328,8 @@ bool WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { NOTREACHED(); content::RecordAction(UserMetricsAction("BadMessageTerminate_WPH")); base::KillProcess( - data().handle, content::RESULT_CODE_KILLED_BAD_MESSAGE, false); + process_->GetData().handle, content::RESULT_CODE_KILLED_BAD_MESSAGE, + false); } if (handled) @@ -490,7 +499,7 @@ void WorkerProcessHost::UpdateTitle() { display_title += *i; } - SetName(ASCIIToUTF16(display_title)); + process_->SetName(ASCIIToUTF16(display_title)); } void WorkerProcessHost::DocumentDetached(WorkerMessageFilter* filter, @@ -512,6 +521,10 @@ void WorkerProcessHost::TerminateWorker(int worker_route_id) { Send(new WorkerMsg_TerminateWorkerContext(worker_route_id)); } +const ChildProcessData& WorkerProcessHost::GetData() { + return process_->GetData(); +} + WorkerProcessHost::WorkerInstance::WorkerInstance( const GURL& url, const string16& name, diff --git a/content/browser/worker_host/worker_process_host.h b/content/browser/worker_host/worker_process_host.h index 6ccc137..57806c8 100644 --- a/content/browser/worker_host/worker_process_host.h +++ b/content/browser/worker_host/worker_process_host.h @@ -11,10 +11,15 @@ #include "base/basictypes.h" #include "base/file_path.h" -#include "content/browser/browser_child_process_host.h" +#include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" #include "content/browser/worker_host/worker_document_set.h" +#include "content/public/browser/browser_child_process_host_delegate.h" +#include "content/public/browser/browser_child_process_host_iterator.h" #include "googleurl/src/gurl.h" +#include "ipc/ipc_message.h" + +class BrowserChildProcessHost; namespace content { class ResourceContext; @@ -27,7 +32,8 @@ class WorkerServiceImpl; // process, but that may change. However, we do assume (by storing a // net::URLRequestContext) that a WorkerProcessHost serves a single // BrowserContext. -class WorkerProcessHost : public BrowserChildProcessHost { +class WorkerProcessHost : public content::BrowserChildProcessHostDelegate, + public IPC::Message::Sender { public: // Contains information about each worker instance, needed to forward messages // between the renderer and worker processes. @@ -110,6 +116,9 @@ class WorkerProcessHost : public BrowserChildProcessHost { explicit WorkerProcessHost(const content::ResourceContext* resource_context); virtual ~WorkerProcessHost(); + // IPC::Message::Sender implementation: + virtual bool Send(IPC::Message* message) OVERRIDE; + // Starts the process. Returns true iff it succeeded. // |render_process_id| is the renderer process responsible for starting this // worker. @@ -132,6 +141,8 @@ class WorkerProcessHost : public BrowserChildProcessHost { // Terminates the given worker, i.e. based on a UI action. CONTENT_EXPORT void TerminateWorker(int worker_route_id); + CONTENT_EXPORT const content::ChildProcessData& GetData(); + typedef std::list<WorkerInstance> Instances; const Instances& instances() const { return instances_; } @@ -145,16 +156,13 @@ class WorkerProcessHost : public BrowserChildProcessHost { Instances& mutable_instances() { return instances_; } private: - // Called when the process has been launched successfully. + // BrowserChildProcessHostDelegate implementation: virtual void OnProcessLaunched() OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; // Creates and adds the message filters. void CreateMessageFilters(int render_process_id); - // IPC::Channel::Listener implementation: - // Called when a message arrives from the worker process. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - void OnWorkerContextClosed(int worker_route_id); void OnAllowDatabase(int worker_route_id, const GURL& url, @@ -186,7 +194,18 @@ class WorkerProcessHost : public BrowserChildProcessHost { // process. scoped_refptr<WorkerMessageFilter> worker_message_filter_; + scoped_ptr<BrowserChildProcessHost> process_; + DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost); }; +class WorkerProcessHostIterator + : public content::BrowserChildProcessHostTypeIterator<WorkerProcessHost> { + public: + WorkerProcessHostIterator() + : content::BrowserChildProcessHostTypeIterator<WorkerProcessHost>( + content::PROCESS_TYPE_WORKER) { + } +}; + #endif // CONTENT_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_ diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc index 9686152..bddd74e 100644 --- a/content/browser/worker_host/worker_service_impl.cc +++ b/content/browser/worker_host/worker_service_impl.cc @@ -15,6 +15,7 @@ #include "content/browser/worker_host/worker_process_host.h" #include "content/common/view_messages.h" #include "content/common/worker_messages.h" +#include "content/public/browser/child_process_data.h" #include "content/public/browser/worker_service_observer.h" #include "content/public/common/content_switches.h" #include "content/public/common/process_type.h" @@ -45,10 +46,8 @@ WorkerServiceImpl::~WorkerServiceImpl() { void WorkerServiceImpl::OnWorkerMessageFilterClosing( WorkerMessageFilter* filter) { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - worker->FilterShutdown(filter); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + iter->FilterShutdown(filter); } // See if that process had any queued workers. @@ -156,10 +155,8 @@ void WorkerServiceImpl::CancelCreateDedicatedWorker( void WorkerServiceImpl::ForwardToWorker(const IPC::Message& message, WorkerMessageFilter* filter) { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - if (worker->FilterMessage(message, filter)) + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter->FilterMessage(message, filter)) return; } @@ -169,11 +166,8 @@ void WorkerServiceImpl::ForwardToWorker(const IPC::Message& message, void WorkerServiceImpl::DocumentDetached(unsigned long long document_id, WorkerMessageFilter* filter) { // Any associated shared workers can be shut down. - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - worker->DocumentDetached(filter, document_id); - } + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) + iter->DocumentDetached(filter, document_id); // Remove any queued shared workers for this document. for (WorkerProcessHost::Instances::iterator iter = queued_workers_.begin(); @@ -309,16 +303,14 @@ WorkerProcessHost* WorkerServiceImpl::GetProcessForDomain(const GURL& url) { int num_processes = 0; std::string domain = net::RegistryControlledDomainService::GetDomainAndRegistry(url); - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { num_processes++; - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); for (WorkerProcessHost::Instances::const_iterator instance = - worker->instances().begin(); - instance != worker->instances().end(); ++instance) { + iter->instances().begin(); + instance != iter->instances().end(); ++instance) { if (net::RegistryControlledDomainService::GetDomainAndRegistry( instance->url()) == domain) { - return worker; + return *iter; } } } @@ -331,8 +323,7 @@ WorkerProcessHost* WorkerServiceImpl::GetProcessForDomain(const GURL& url) { WorkerProcessHost* WorkerServiceImpl::GetProcessToFillUpCores() { int num_processes = 0; - BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - for (; !iter.Done(); ++iter) + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) num_processes++; if (num_processes >= base::SysInfo::NumberOfProcessors()) @@ -343,11 +334,9 @@ WorkerProcessHost* WorkerServiceImpl::GetProcessToFillUpCores() { WorkerProcessHost* WorkerServiceImpl::GetLeastLoadedWorker() { WorkerProcessHost* smallest = NULL; - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - if (!smallest || worker->instances().size() < smallest->instances().size()) - smallest = worker; + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (!smallest || iter->instances().size() < smallest->instances().size()) + smallest = *iter; } return smallest; @@ -385,12 +374,10 @@ bool WorkerServiceImpl::TabCanCreateWorkerProcess( int total_workers = 0; int workers_per_tab = 0; *hit_total_worker_limit = false; - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { for (WorkerProcessHost::Instances::const_iterator cur_instance = - worker->instances().begin(); - cur_instance != worker->instances().end(); ++cur_instance) { + iter->instances().begin(); + cur_instance != iter->instances().end(); ++cur_instance) { total_workers++; if (total_workers >= kMaxWorkersWhenSeparate) { *hit_total_worker_limit = true; @@ -433,16 +420,14 @@ void WorkerServiceImpl::TryStartingQueuedWorker() { bool WorkerServiceImpl::GetRendererForWorker(int worker_process_id, int* render_process_id, int* render_view_id) const { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - if (iter->data().id != worker_process_id) + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter.GetData().id != worker_process_id) continue; // This code assumes one worker per process, see function comment in header! - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); WorkerProcessHost::Instances::const_iterator first_instance = - worker->instances().begin(); - if (first_instance == worker->instances().end()) + iter->instances().begin(); + if (first_instance == iter->instances().end()) return false; WorkerDocumentSet::DocumentInfoSet::const_iterator info = @@ -456,15 +441,13 @@ bool WorkerServiceImpl::GetRendererForWorker(int worker_process_id, const WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindWorkerInstance( int worker_process_id) { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - if (iter->data().id != worker_process_id) + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { + if (iter.GetData().id != worker_process_id) continue; - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); WorkerProcessHost::Instances::const_iterator instance = - worker->instances().begin(); - return instance == worker->instances().end() ? NULL : &*instance; + iter->instances().begin(); + return instance == iter->instances().end() ? NULL : &*instance; } return NULL; } @@ -496,12 +479,10 @@ WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( const GURL& url, const string16& name, const content::ResourceContext* resource_context) { - for (BrowserChildProcessHost::Iterator iter(content::PROCESS_TYPE_WORKER); - !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); + for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { for (WorkerProcessHost::Instances::iterator instance_iter = - worker->mutable_instances().begin(); - instance_iter != worker->mutable_instances().end(); + iter->mutable_instances().begin(); + instance_iter != iter->mutable_instances().end(); ++instance_iter) { if (instance_iter->Matches(url, name, resource_context)) return &(*instance_iter); diff --git a/content/content_browser.gypi b/content/content_browser.gypi index f60b942..2503c7b 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -27,6 +27,11 @@ 'sources': [ 'public/browser/access_token_store.cc', 'public/browser/access_token_store.h', + 'public/browser/browser_child_process_host.h', + 'public/browser/browser_child_process_host_delegate.cc', + 'public/browser/browser_child_process_host_delegate.h', + 'public/browser/browser_child_process_host_iterator.cc', + 'public/browser/browser_child_process_host_iterator.h', 'public/browser/browser_context.h', 'public/browser/browser_main_parts.h', 'public/browser/browser_message_filter.cc', diff --git a/content/content_common.gypi b/content/content_common.gypi index 8f791b0..4be564af5 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -30,6 +30,7 @@ 'sources': [ 'public/common/bindings_policy.h', 'public/common/child_process_host.h', + 'public/common/child_process_host_delegate.cc', 'public/common/child_process_host_delegate.h', 'public/common/child_process_sandbox_support_linux.h', 'public/common/content_constants.cc', diff --git a/content/public/browser/DEPS b/content/public/browser/DEPS index 85dabc6..ca317ea 100644 --- a/content/public/browser/DEPS +++ b/content/public/browser/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+content/browser/browser_child_process_host.h", "+content/browser/notification_service_impl.h", "+content/browser/renderer_host/render_view_host.h", diff --git a/content/public/browser/browser_child_process_host.h b/content/public/browser/browser_child_process_host.h new file mode 100644 index 0000000..e4b6da3 --- /dev/null +++ b/content/public/browser/browser_child_process_host.h @@ -0,0 +1,70 @@ +// Copyright (c) 2012 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 CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_H_ +#define CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_H_ +#pragma once + +#include "base/process_util.h" +#include "base/string16.h" +#include "build/build_config.h" +#include "content/common/content_export.h" +#include "content/public/common/process_type.h" +#include "ipc/ipc_message.h" + +class CommandLine; +class FilePath; + +namespace content { + +class BrowserChildProcessHostDelegate; +class ChildProcessHost; +struct ChildProcessData; + +// This represents child processes of the browser process, i.e. plugins. They +// will get terminated at browser shutdown. +class CONTENT_EXPORT BrowserChildProcessHost : public IPC::Message::Sender { + public: + // Used to create a child process host. The delegate must outlive this object. + static BrowserChildProcessHost* Create( + ProcessType type, + BrowserChildProcessHostDelegate* delegate); + + virtual ~BrowserChildProcessHost() {} + + // Derived classes call this to launch the child process asynchronously. + virtual void Launch( +#if defined(OS_WIN) + const FilePath& exposed_dir, +#elif defined(OS_POSIX) + bool use_zygote, + const base::environment_vector& environ, +#endif + CommandLine* cmd_line) = 0; + + virtual const ChildProcessData& GetData() const = 0; + + // Returns the ChildProcessHost object used by this object. + virtual ChildProcessHost* GetHost() const = 0; + + // Returns the termination status of a child. |exit_code| is the + // status returned when the process exited (for posix, as returned + // from waitpid(), for Windows, as returned from + // GetExitCodeProcess()). |exit_code| may be NULL. + virtual base::TerminationStatus GetTerminationStatus(int* exit_code) = 0; + + // Sets the user-visible name of the process. + virtual void SetName(const string16& name) = 0; + + // Set the handle of the process. BrowserChildProcessHost will do this when + // the Launch method is used to start the process. However if the owner + // of this object doesn't call Launch and starts the process in another way, + // they need to call this method so that the process handle is associated with + // this object. + virtual void SetHandle(base::ProcessHandle handle) = 0; +}; + +}; // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_H_ diff --git a/content/public/browser/browser_child_process_host_delegate.cc b/content/public/browser/browser_child_process_host_delegate.cc new file mode 100644 index 0000000..06a7c6d --- /dev/null +++ b/content/public/browser/browser_child_process_host_delegate.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2012 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 "content/public/browser/browser_child_process_host_delegate.h" + +namespace content { + +bool BrowserChildProcessHostDelegate::CanShutdown() { + return true; +} + +} // namespace content diff --git a/content/public/browser/browser_child_process_host_delegate.h b/content/public/browser/browser_child_process_host_delegate.h new file mode 100644 index 0000000..5c82d05 --- /dev/null +++ b/content/public/browser/browser_child_process_host_delegate.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 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 CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_DELEGATE_H_ +#define CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_DELEGATE_H_ +#pragma once + +#include "content/common/content_export.h" +#include "ipc/ipc_channel.h" + +namespace content { + +// Interface that all users of BrowserChildProcessHost need to provide. +class BrowserChildProcessHostDelegate : public IPC::Channel::Listener { + public: + virtual ~BrowserChildProcessHostDelegate() {} + + // Delegates return true if it's ok to shut down the child process (which is + // the default return value). The exception is if the host is in the middle of + // sending a request to the process, in which case the other side might think + // it's ok to shutdown, when really it's not. + CONTENT_EXPORT virtual bool CanShutdown(); + + // Called when the process has been started. + virtual void OnProcessLaunched() {} + + // Called if the process crashed. |exit_code| is the status returned when the + // process crashed (for posix, as returned from waitpid(), for Windows, as + // returned from GetExitCodeProcess()). + virtual void OnProcessCrashed(int exit_code) {} +}; + +}; // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_DELEGATE_H_ diff --git a/content/public/browser/browser_child_process_host_iterator.cc b/content/public/browser/browser_child_process_host_iterator.cc new file mode 100644 index 0000000..534a431 --- /dev/null +++ b/content/public/browser/browser_child_process_host_iterator.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2012 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 "content/public/browser/browser_child_process_host_iterator.h" + +#include "base/logging.h" +#include "content/browser/browser_child_process_host.h" +#include "content/public/browser/browser_thread.h" + +namespace content { + +BrowserChildProcessHostIterator::BrowserChildProcessHostIterator() + : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << + "BrowserChildProcessHostIterator must be used on the IO thread."; + iterator_ = ::BrowserChildProcessHost::GetIterator()->begin(); +} + +BrowserChildProcessHostIterator::BrowserChildProcessHostIterator( + content::ProcessType type) + : all_(false), type_(type) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << + "BrowserChildProcessHostIterator must be used on the IO thread."; + iterator_ = ::BrowserChildProcessHost::GetIterator()->begin(); + if (!Done() && (*iterator_)->GetData().type != type_) + ++(*this); +} + +bool BrowserChildProcessHostIterator::operator++() { + CHECK(!Done()); + do { + ++iterator_; + if (Done()) + break; + + if (!all_ && (*iterator_)->GetData().type != type_) + continue; + + return true; + } while (true); + + return false; +} + +bool BrowserChildProcessHostIterator::Done() { + return iterator_ == ::BrowserChildProcessHost::GetIterator()->end(); +} + +const ChildProcessData& BrowserChildProcessHostIterator::GetData() { + CHECK(!Done()); + return (*iterator_)->GetData(); +} + +bool BrowserChildProcessHostIterator::Send(IPC::Message* message) { + CHECK(!Done()); + return (*iterator_)->Send(message); +} + +BrowserChildProcessHostDelegate* + BrowserChildProcessHostIterator::GetDelegate() { + return (*iterator_)->delegate(); +} + +} // namespace content diff --git a/content/public/browser/browser_child_process_host_iterator.h b/content/public/browser/browser_child_process_host_iterator.h new file mode 100644 index 0000000..357d708 --- /dev/null +++ b/content/public/browser/browser_child_process_host_iterator.h @@ -0,0 +1,68 @@ +// Copyright (c) 2012 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 CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_ITERATOR_H_ +#define CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_ITERATOR_H_ +#pragma once + +#include <list> + +#include "content/common/content_export.h" +#include "content/public/common/process_type.h" + +class BrowserChildProcessHost; + +namespace IPC { +class Message; +} + +namespace content { + +class BrowserChildProcessHostDelegate; +struct ChildProcessData; + +// This class allows iteration through either all child processes, or ones of a +// specific type, depending on which constructor is used. Note that this should +// be done from the IO thread and that the iterator should not be kept around as +// it may be invalidated on subsequent event processing in the event loop. +class CONTENT_EXPORT BrowserChildProcessHostIterator { + public: + BrowserChildProcessHostIterator(); + explicit BrowserChildProcessHostIterator(content::ProcessType type); + + // These methods work on the current iterator object. Only call them if + // Done() returns false. + bool operator++(); + bool Done(); + const ChildProcessData& GetData(); + bool Send(IPC::Message* message); + BrowserChildProcessHostDelegate* GetDelegate(); + + private: + bool all_; + content::ProcessType type_; + std::list<BrowserChildProcessHost*>::iterator iterator_; +}; + +// Helper class so that subclasses of BrowserChildProcessHostDelegate can be +// iterated with no casting needing. Note that because of the components build, +// this class can only be used by BCPHD implementations that live in content, +// otherwise link errors will result. +template <class T> +class CONTENT_EXPORT BrowserChildProcessHostTypeIterator + : public BrowserChildProcessHostIterator { + public: + explicit BrowserChildProcessHostTypeIterator(content::ProcessType type) + : BrowserChildProcessHostIterator(type) {} + T* operator->() { + return static_cast<T*>(GetDelegate()); + } + T* operator*() { + return static_cast<T*>(GetDelegate()); + } +}; + +}; // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_ITERATOR_H_ diff --git a/content/public/common/child_process_host.h b/content/public/common/child_process_host.h index 8c85091..499ac2e 100644 --- a/content/public/common/child_process_host.h +++ b/content/public/common/child_process_host.h @@ -16,7 +16,9 @@ namespace content { class ChildProcessHostDelegate; -// Interface that all users of ChildProcessHost need to provide. +// This represents a non-browser process. This can include traditional child +// processes like plugins, or an embedder could even use this for long lived +// processes that run independent of the browser process. class CONTENT_EXPORT ChildProcessHost : public IPC::Message::Sender { public: virtual ~ChildProcessHost() {} diff --git a/content/public/common/child_process_host_delegate.cc b/content/public/common/child_process_host_delegate.cc new file mode 100644 index 0000000..85b0398 --- /dev/null +++ b/content/public/common/child_process_host_delegate.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2012 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 "content/public/common/child_process_host_delegate.h" + +namespace content { + +bool ChildProcessHostDelegate::CanShutdown() { + return true; +} + +} // namespace content diff --git a/content/public/common/child_process_host_delegate.h b/content/public/common/child_process_host_delegate.h index 7b9cbd1..4418e611 100644 --- a/content/public/common/child_process_host_delegate.h +++ b/content/public/common/child_process_host_delegate.h @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_ -#define CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_ +#ifndef CONTENT_PUBLIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_ +#define CONTENT_PUBLIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_ #pragma once #include <string> +#include "content/common/content_export.h" #include "ipc/ipc_channel.h" namespace content { @@ -17,20 +18,20 @@ class ChildProcessHostDelegate : public IPC::Channel::Listener { public: virtual ~ChildProcessHostDelegate() {} - // Derived classes return true if it's ok to shut down the child process. - // Normally they would return true. The exception is if the host is in the - // middle of sending a request to the process, in which case the other side - // might think it's ok to shutdown, when really it's not. - virtual bool CanShutdown() = 0; + // Delegates return true if it's ok to shut down the child process (which is + // the default return value). The exception is if the host is in the middle of + // sending a request to the process, in which case the other side might think + // it's ok to shutdown, when really it's not. + CONTENT_EXPORT virtual bool CanShutdown(); // Notifies the derived class that we told the child process to kill itself. - virtual void ShutdownStarted() = 0; + virtual void ShutdownStarted() {} // Called when the child process unexpected closes the IPC channel. Delegates // would normally delete the object in this case. - virtual void OnChildDisconnected() = 0; + virtual void OnChildDisconnected() {} }; }; // namespace content -#endif // CONTENT_PULIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_ +#endif // CONTENT_PUBLIC_COMMON_CHILD_PROCESS_HOST_DELEGATE_H_ |