| 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
|
|
|