Index: content/public/browser/browser_message_filter.cc |
=================================================================== |
--- content/public/browser/browser_message_filter.cc (revision 225900) |
+++ content/public/browser/browser_message_filter.cc (working copy) |
@@ -18,52 +18,87 @@ |
namespace content { |
-BrowserMessageFilter::BrowserMessageFilter() |
- : channel_(NULL), |
-#if defined(OS_WIN) |
- peer_handle_(base::kNullProcessHandle), |
-#endif |
- peer_pid_(base::kNullProcessId) { |
-} |
+class BrowserMessageFilter::Internal : public IPC::ChannelProxy::MessageFilter { |
+ public: |
+ explicit Internal(BrowserMessageFilter* filter) : filter_(filter) {} |
-void BrowserMessageFilter::OnFilterAdded(IPC::Channel* channel) { |
- channel_ = channel; |
-} |
+ private: |
+ virtual ~Internal() {} |
-void BrowserMessageFilter::OnChannelClosing() { |
- channel_ = NULL; |
-} |
+ // IPC::ChannelProxy::MessageFilter implementation: |
+ virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE { |
+ filter_->channel_ = channel; |
+ filter_->OnFilterAdded(channel); |
+ } |
-void BrowserMessageFilter::OnChannelConnected(int32 peer_pid) { |
- peer_pid_ = peer_pid; |
-} |
+ virtual void OnFilterRemoved() OVERRIDE { |
+ filter_->OnFilterRemoved(); |
+ } |
-bool BrowserMessageFilter::OnMessageReceived(const IPC::Message& message) { |
- BrowserThread::ID thread = BrowserThread::IO; |
- OverrideThreadForMessage(message, &thread); |
+ virtual void OnChannelClosing() OVERRIDE { |
+ filter_->channel_ = NULL; |
+ filter_->OnChannelClosing(); |
+ } |
- if (thread == BrowserThread::IO) { |
- scoped_refptr<base::TaskRunner> runner = |
- OverrideTaskRunnerForMessage(message); |
- if (runner.get()) { |
- runner->PostTask( |
- FROM_HERE, |
- base::Bind(base::IgnoreResult(&BrowserMessageFilter::DispatchMessage), |
- this, |
- message)); |
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { |
+ filter_->peer_pid_ = peer_pid; |
+ filter_->OnChannelConnected(peer_pid); |
+ } |
+ |
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
+ BrowserThread::ID thread = BrowserThread::IO; |
+ filter_->OverrideThreadForMessage(message, &thread); |
+ |
+ if (thread == BrowserThread::IO) { |
+ scoped_refptr<base::TaskRunner> runner = |
+ filter_->OverrideTaskRunnerForMessage(message); |
+ if (runner.get()) { |
+ runner->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ base::IgnoreResult(&Internal::DispatchMessage), this, message)); |
+ return true; |
+ } |
+ return DispatchMessage(message); |
+ } |
+ |
+ if (thread == BrowserThread::UI && |
+ !BrowserMessageFilter::CheckCanDispatchOnUI(message, filter_)) { |
return true; |
} |
- return DispatchMessage(message); |
- } |
- if (thread == BrowserThread::UI && !CheckCanDispatchOnUI(message, this)) |
+ BrowserThread::PostTask( |
+ thread, FROM_HERE, |
+ base::Bind( |
+ base::IgnoreResult(&Internal::DispatchMessage), this, message)); |
return true; |
+ } |
- BrowserThread::PostTask( |
- thread, FROM_HERE, |
- base::Bind(base::IgnoreResult(&BrowserMessageFilter::DispatchMessage), |
- this, message)); |
- return true; |
+ // Dispatches a message to the derived class. |
+ bool DispatchMessage(const IPC::Message& message) { |
+ bool message_was_ok = true; |
+ bool rv = filter_->OnMessageReceived(message, &message_was_ok); |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) || rv) << |
+ "Must handle messages that were dispatched to another thread!"; |
+ if (!message_was_ok) { |
+ content::RecordAction(UserMetricsAction("BadMessageTerminate_BMF")); |
+ filter_->BadMessageReceived(); |
+ } |
+ |
+ return rv; |
+ } |
+ |
+ scoped_refptr<BrowserMessageFilter> filter_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Internal); |
+}; |
+ |
+BrowserMessageFilter::BrowserMessageFilter() |
+ : internal_(NULL), channel_(NULL), |
+#if defined(OS_WIN) |
+ peer_handle_(base::kNullProcessHandle), |
+#endif |
+ peer_pid_(base::kNullProcessId) { |
} |
base::ProcessHandle BrowserMessageFilter::PeerHandle() { |
@@ -80,6 +115,11 @@ |
#endif |
} |
+ |
+void BrowserMessageFilter::OnDestruct() const { |
+ delete this; |
+} |
+ |
bool BrowserMessageFilter::Send(IPC::Message* message) { |
if (message->is_sync()) { |
// We don't support sending synchronous messages from the browser. If we |
@@ -106,10 +146,6 @@ |
return false; |
} |
-void BrowserMessageFilter::OverrideThreadForMessage(const IPC::Message& message, |
- BrowserThread::ID* thread) { |
-} |
- |
base::TaskRunner* BrowserMessageFilter::OverrideTaskRunnerForMessage( |
const IPC::Message& message) { |
return NULL; |
@@ -152,17 +188,12 @@ |
#endif |
} |
-bool BrowserMessageFilter::DispatchMessage(const IPC::Message& message) { |
- bool message_was_ok = true; |
- bool rv = OnMessageReceived(message, &message_was_ok); |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) || rv) << |
- "Must handle messages that were dispatched to another thread!"; |
- if (!message_was_ok) { |
- content::RecordAction(UserMetricsAction("BadMessageTerminate_BMF")); |
- BadMessageReceived(); |
- } |
- |
- return rv; |
+IPC::ChannelProxy::MessageFilter* BrowserMessageFilter::GetFilter() { |
+ // We create this on demand so that if a filter is used in a unit test but |
+ // never attached to a channel, we don't leak Internal and this; |
+ DCHECK(!internal_) << "Should only be called once."; |
+ internal_ = new Internal(this); |
+ return internal_; |
} |
} // namespace content |