summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/browser/browser_child_process_host_impl.cc64
-rw-r--r--content/browser/browser_child_process_host_impl.h13
-rw-r--r--content/browser/mach_broker_mac.cc21
-rw-r--r--content/browser/mach_broker_mac.h8
-rw-r--r--content/browser/media/webrtc_internals.cc28
-rw-r--r--content/browser/media/webrtc_internals.h11
-rw-r--r--content/browser/plugin_process_host.cc5
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/public/browser/browser_child_process_observer.cc22
-rw-r--r--content/public/browser/browser_child_process_observer.h44
-rw-r--r--content/public/browser/notification_types.h31
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.