diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/browser_child_process_host_impl.cc | 64 | ||||
-rw-r--r-- | content/browser/browser_child_process_host_impl.h | 13 | ||||
-rw-r--r-- | content/browser/mach_broker_mac.cc | 21 | ||||
-rw-r--r-- | content/browser/mach_broker_mac.h | 8 | ||||
-rw-r--r-- | content/browser/media/webrtc_internals.cc | 28 | ||||
-rw-r--r-- | content/browser/media/webrtc_internals.h | 11 | ||||
-rw-r--r-- | content/browser/plugin_process_host.cc | 5 | ||||
-rw-r--r-- | content/content_browser.gypi | 2 | ||||
-rw-r--r-- | content/public/browser/browser_child_process_observer.cc | 22 | ||||
-rw-r--r-- | content/public/browser/browser_child_process_observer.h | 44 | ||||
-rw-r--r-- | content/public/browser/notification_types.h | 31 |
11 files changed, 170 insertions, 79 deletions
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index f752330..12712be 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc @@ -22,11 +22,10 @@ #include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_child_process_host_delegate.h" +#include "content/public/browser/browser_child_process_observer.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/notification_service.h" -#include "content/public/browser/notification_types.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" @@ -40,13 +39,22 @@ namespace { static base::LazyInstance<BrowserChildProcessHostImpl::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 ChildProcessData& data) { - NotificationService::current()->Notify( - notification_type, NotificationService::AllSources(), - Details<const ChildProcessData>(&data)); +base::LazyInstance<ObserverList<BrowserChildProcessObserver> > + g_observers = LAZY_INSTANCE_INITIALIZER; + +void NotifyProcessHostConnected(const ChildProcessData& data) { + FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), + BrowserChildProcessHostConnected(data)); +} + +void NotifyProcessHostDisconnected(const ChildProcessData& data) { + FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), + BrowserChildProcessHostDisconnected(data)); +} + +void NotifyProcessCrashed(const ChildProcessData& data) { + FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), + BrowserChildProcessCrashed(data)); } } // namespace @@ -63,11 +71,26 @@ base::ProcessMetrics::PortProvider* BrowserChildProcessHost::GetPortProvider() { } #endif +// static BrowserChildProcessHostImpl::BrowserChildProcessList* BrowserChildProcessHostImpl::GetIterator() { return g_child_process_list.Pointer(); } +// static +void BrowserChildProcessHostImpl::AddObserver( + BrowserChildProcessObserver* observer) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + g_observers.Get().AddObserver(observer); +} + +// static +void BrowserChildProcessHostImpl::RemoveObserver( + BrowserChildProcessObserver* observer) { + // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126. + g_observers.Get().RemoveObserver(observer); +} + BrowserChildProcessHostImpl::BrowserChildProcessHostImpl( ProcessType type, BrowserChildProcessHostDelegate* delegate) @@ -182,11 +205,11 @@ void BrowserChildProcessHostImpl::SetTerminateChildOnShutdown( child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); } -void BrowserChildProcessHostImpl::Notify(int type) { - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&ChildNotificationHelper, type, data_)); +void BrowserChildProcessHostImpl::NotifyProcessInstanceCreated( + const ChildProcessData& data) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), + BrowserChildProcessInstanceCreated(data)); } base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus( @@ -204,7 +227,9 @@ bool BrowserChildProcessHostImpl::OnMessageReceived( } void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { - Notify(NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&NotifyProcessHostConnected, data_)); delegate_->OnChannelConnected(peer_pid); } @@ -217,6 +242,7 @@ bool BrowserChildProcessHostImpl::CanShutdown() { } void BrowserChildProcessHostImpl::OnChildDisconnected() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(data_.handle != base::kNullProcessHandle); int exit_code; base::TerminationStatus status = GetTerminationStatus(&exit_code); @@ -224,8 +250,8 @@ void BrowserChildProcessHostImpl::OnChildDisconnected() { case base::TERMINATION_STATUS_PROCESS_CRASHED: case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { delegate_->OnProcessCrashed(exit_code); - // Report that this child process crashed. - Notify(NOTIFICATION_CHILD_PROCESS_CRASHED); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&NotifyProcessCrashed, data_)); UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", data_.type, PROCESS_TYPE_MAX); @@ -250,8 +276,8 @@ void BrowserChildProcessHostImpl::OnChildDisconnected() { UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", data_.type, PROCESS_TYPE_MAX); - // Notify in the main loop of the disconnection. - Notify(NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, + base::Bind(&NotifyProcessHostDisconnected, data_)); delete delegate_; // Will delete us } diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h index efbf78e..5ecaddaa 100644 --- a/content/browser/browser_child_process_host_impl.h +++ b/content/browser/browser_child_process_host_impl.h @@ -16,7 +16,9 @@ #include "content/public/common/child_process_host_delegate.h" namespace content { + class BrowserChildProcessHostIterator; +class BrowserChildProcessObserver; // 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 @@ -62,18 +64,21 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl // shutdown. Default is to always terminate. void SetTerminateChildOnShutdown(bool terminate_on_shutdown); - // Sends the given notification on the UI thread. - void Notify(int type); + // Called when an instance of a particular child is created in a page. + static void NotifyProcessInstanceCreated(const ChildProcessData& data); - BrowserChildProcessHostDelegate* delegate() const { return delegate_; - } + BrowserChildProcessHostDelegate* delegate() const { return delegate_; } typedef std::list<BrowserChildProcessHostImpl*> BrowserChildProcessList; private: friend class BrowserChildProcessHostIterator; + friend class BrowserChildProcessObserver; static BrowserChildProcessList* GetIterator(); + static void AddObserver(BrowserChildProcessObserver* observer); + static void RemoveObserver(BrowserChildProcessObserver* observer); + // ChildProcessHostDelegate implementation: virtual bool CanShutdown() OVERRIDE; virtual void OnChildDisconnected() OVERRIDE; diff --git a/content/browser/mach_broker_mac.cc b/content/browser/mach_broker_mac.cc index 466c84d..325db75 100644 --- a/content/browser/mach_broker_mac.cc +++ b/content/browser/mach_broker_mac.cc @@ -172,6 +172,15 @@ mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { return it->second.mach_task_; } +void MachBroker::BrowserChildProcessHostDisconnected( + const ChildProcessData& data) { + InvalidatePid(data.handle); +} + +void MachBroker::BrowserChildProcessCrashed(const ChildProcessData& data) { + InvalidatePid(data.handle); +} + void MachBroker::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { @@ -187,10 +196,6 @@ void MachBroker::Observe(int type, case NOTIFICATION_RENDERER_PROCESS_TERMINATED: handle = Source<RenderProcessHost>(source)->GetHandle(); break; - case NOTIFICATION_CHILD_PROCESS_CRASHED: - case NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED: - handle = Details<ChildProcessData>(details)->handle; - break; default: NOTREACHED() << "Unexpected notification"; break; @@ -218,10 +223,10 @@ void MachBroker::RegisterNotifications() { NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, NotificationService::AllBrowserContextsAndSources()); - registrar_.Add(this, NOTIFICATION_CHILD_PROCESS_CRASHED, - NotificationService::AllBrowserContextsAndSources()); - registrar_.Add(this, NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED, - NotificationService::AllBrowserContextsAndSources()); + + // No corresponding StopObservingBrowserChildProcesses, + // we leak this singleton. + BrowserChildProcessObserver::Add(this); } } // namespace content diff --git a/content/browser/mach_broker_mac.h b/content/browser/mach_broker_mac.h index de83d44..011df04 100644 --- a/content/browser/mach_broker_mac.h +++ b/content/browser/mach_broker_mac.h @@ -14,6 +14,7 @@ #include "base/process.h" #include "base/process_util.h" #include "base/synchronization/lock.h" +#include "content/public/browser/browser_child_process_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -34,6 +35,7 @@ namespace content { // Since this data arrives over a separate channel, it is not available // immediately after a child process has been started. class CONTENT_EXPORT MachBroker : public base::ProcessMetrics::PortProvider, + public BrowserChildProcessObserver, public NotificationObserver { public: // Returns the global MachBroker. @@ -82,6 +84,12 @@ class CONTENT_EXPORT MachBroker : public base::ProcessMetrics::PortProvider, // Implement |ProcessMetrics::PortProvider|. virtual mach_port_t TaskForPid(base::ProcessHandle process) const OVERRIDE; + // Implement |BrowserChildProcessObserver|. + virtual void BrowserChildProcessHostDisconnected( + const ChildProcessData& data) OVERRIDE; + virtual void BrowserChildProcessCrashed( + const ChildProcessData& data) OVERRIDE; + // Implement |NotificationObserver|. virtual void Observe(int type, const NotificationSource& source, diff --git a/content/browser/media/webrtc_internals.cc b/content/browser/media/webrtc_internals.cc index ce5028a..34703f5 100644 --- a/content/browser/media/webrtc_internals.cc +++ b/content/browser/media/webrtc_internals.cc @@ -35,11 +35,12 @@ static ListValue* EnsureLogList(DictionaryValue* dict) { WebRTCInternals::WebRTCInternals() { registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, NotificationService::AllBrowserContextsAndSources()); - registrar_.Add(this, NOTIFICATION_CHILD_PROCESS_CRASHED, - NotificationService::AllBrowserContextsAndSources()); + + BrowserChildProcessObserver::Add(this); } WebRTCInternals::~WebRTCInternals() { + BrowserChildProcessObserver::Remove(this); } WebRTCInternals* WebRTCInternals::GetInstance() { @@ -178,24 +179,21 @@ void WebRTCInternals::SendUpdate(const string& command, Value* value) { OnUpdate(command, value)); } +void WebRTCInternals::BrowserChildProcessCrashed( + const ChildProcessData& data) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + OnRendererExit(data.id); +} + void WebRTCInternals::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - int render_process_id = -1; - - switch (type) { - case NOTIFICATION_RENDERER_PROCESS_TERMINATED: - render_process_id = Source<RenderProcessHost>(source)->GetID(); - break; - case NOTIFICATION_CHILD_PROCESS_CRASHED: - render_process_id = Details<ChildProcessData>(details).ptr()->id; - break; - default: - NOTREACHED(); - break; - } + DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED); + OnRendererExit(Source<RenderProcessHost>(source)->GetID()); +} +void WebRTCInternals::OnRendererExit(int render_process_id) { // Iterates from the end of the list to remove the PeerConnections created // by the exitting renderer. for (int i = peer_connection_data_.GetSize() - 1; i >= 0; --i) { diff --git a/content/browser/media/webrtc_internals.h b/content/browser/media/webrtc_internals.h index 402b643..7baff52 100644 --- a/content/browser/media/webrtc_internals.h +++ b/content/browser/media/webrtc_internals.h @@ -10,6 +10,7 @@ #include "base/process.h" #include "base/values.h" #include "content/common/content_export.h" +#include "content/public/browser/browser_child_process_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -20,7 +21,8 @@ class WebRTCInternalsUIObserver; // It collects peer connection infomation from the renderers, // forwards the data to WebRTCInternalsUIObserver and // sends data collecting commands to the renderers. -class CONTENT_EXPORT WebRTCInternals : public NotificationObserver{ +class CONTENT_EXPORT WebRTCInternals : public BrowserChildProcessObserver, + public NotificationObserver{ public: static WebRTCInternals* GetInstance(); @@ -71,11 +73,18 @@ class CONTENT_EXPORT WebRTCInternals : public NotificationObserver{ void SendUpdate(const std::string& command, base::Value* value); + // BrowserChildProcessObserver implementation. + virtual void BrowserChildProcessCrashed( + const ChildProcessData& data) OVERRIDE; + // NotificationObserver implementation. virtual void Observe(int type, const NotificationSource& source, const NotificationDetails& details) OVERRIDE; + // Called when a renderer exits (including crashes). + void OnRendererExit(int render_process_id); + ObserverList<WebRTCInternalsUIObserver> observers_; // |peer_connection_data_| is a list containing all the PeerConnection diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index 62be9db7..be2e558 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -342,7 +342,10 @@ void PluginProcessHost::CancelPendingRequestsForResourceContext( } void PluginProcessHost::OpenChannelToPlugin(Client* client) { - process_->Notify(NOTIFICATION_CHILD_INSTANCE_CREATED); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&BrowserChildProcessHostImpl::NotifyProcessInstanceCreated, + process_->GetData())); client->SetPluginInfo(info_); if (process_->GetHost()->IsChannelOpening()) { // The channel is already in the process of being opened. Put diff --git a/content/content_browser.gypi b/content/content_browser.gypi index c4d75be..4032dda 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -36,6 +36,8 @@ '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_child_process_observer.cc', + 'public/browser/browser_child_process_observer.h', 'public/browser/browser_context.h', 'public/browser/browser_ipc_logging.h', 'public/browser/browser_main_parts.cc', diff --git a/content/public/browser/browser_child_process_observer.cc b/content/public/browser/browser_child_process_observer.cc new file mode 100644 index 0000000..9f0be9b --- /dev/null +++ b/content/public/browser/browser_child_process_observer.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/browser_child_process_observer.h" + +#include "content/browser/browser_child_process_host_impl.h" + +namespace content { + +// static +void BrowserChildProcessObserver::Add(BrowserChildProcessObserver* observer) { + BrowserChildProcessHostImpl::AddObserver(observer); +} + +// static +void BrowserChildProcessObserver::Remove( + BrowserChildProcessObserver* observer) { + BrowserChildProcessHostImpl::RemoveObserver(observer); +} + +} // namespace content diff --git a/content/public/browser/browser_child_process_observer.h b/content/public/browser/browser_child_process_observer.h new file mode 100644 index 0000000..12e4355 --- /dev/null +++ b/content/public/browser/browser_child_process_observer.h @@ -0,0 +1,44 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_OBSERVER_H_ +#define CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_OBSERVER_H_ + +#include "content/common/content_export.h" + +namespace content { + +struct ChildProcessData; + +// An observer API implemented by classes which are interested +// in browser child process events. +class CONTENT_EXPORT BrowserChildProcessObserver { + public: + // Called when a child process host has connected to a child process. + virtual void BrowserChildProcessHostConnected(const ChildProcessData& data) {} + + // Called after a ChildProcessHost is disconnected from the child process. + virtual void BrowserChildProcessHostDisconnected( + const ChildProcessData& data) {} + + // Called when a child process disappears unexpectedly as a result of a crash. + virtual void BrowserChildProcessCrashed(const ChildProcessData& data) {} + + // Called when an instance of a particular child is created in a page. If one + // page contains several regions rendered by the same child, this will be + // called once for each region during the page load. + virtual void BrowserChildProcessInstanceCreated( + const ChildProcessData& data) {} + + protected: + // The observer can be destroyed on any thread. + virtual ~BrowserChildProcessObserver() {} + + static void Add(BrowserChildProcessObserver* observer); + static void Remove(BrowserChildProcessObserver* observer); +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_OBSERVER_H_ diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h index beeafd3..0878539 100644 --- a/content/public/browser/notification_types.h +++ b/content/public/browser/notification_types.h @@ -257,37 +257,6 @@ enum NotificationType { // The source is the RenderViewHost, the details are not used. NOTIFICATION_ACCESSIBILITY_OTHER, - // Child Processes --------------------------------------------------------- - - // This notification is sent when a child process host has connected to a - // child process. There is no usable source, since it is sent from an - // ephemeral task; register for AllSources() to receive this notification. - // The details are in a Details<ChildProcessData>. - NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED, - - // This message is sent after a ChildProcessHost is disconnected from the - // child process. There is no usable source, since it is sent from an - // ephemeral task; register for AllSources() to receive this notification. - // The details are in a Details<ChildProcessData>. - NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED, - - // This message is sent when a child process disappears - // unexpectedly as a result of a crash. There is no usable - // source, since it is sent from an ephemeral task; register for - // AllSources() to receive this notification. The details are in - // a Details<ChildProcessData>. - NOTIFICATION_CHILD_PROCESS_CRASHED, - - // This message indicates that an instance of a particular child was - // created in a page. (If one page contains several regions rendered by - // the same child, this notification will occur once for each region - // during the page load.) - // - // There is no usable source, since it is sent from an ephemeral task; - // register for AllSources() to receive this notification. The details are - // in a Details<ChildProcessData>. - NOTIFICATION_CHILD_INSTANCE_CREATED, - // Miscellaneous ------------------------------------------------------------- // Sent before the repost form warning is brought up. |