diff --git a/chrome/browser/appcache/appcache_dispatcher_host.cc b/chrome/browser/appcache/appcache_dispatcher_host.cc
index 60172ea0c221fbf6d9f583f1d55f0dce4e5593dc..8bcf53e7f1e47fbbbedfebcb343cd37a49080cde 100644
--- a/chrome/browser/appcache/appcache_dispatcher_host.cc
+++ b/chrome/browser/appcache/appcache_dispatcher_host.cc
@@ -60,20 +60,19 @@ void AppCacheDispatcherHost::OnChannelConnected(int32 peer_pid) {
 bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message,
                                                bool* message_was_ok) {
   bool handled = true;
-
   IPC_BEGIN_MESSAGE_MAP_EX(AppCacheDispatcherHost, message, *message_was_ok)
-    IPC_MESSAGE_HANDLER(AppCacheMsg_RegisterHost, OnRegisterHost);
-    IPC_MESSAGE_HANDLER(AppCacheMsg_UnregisterHost, OnUnregisterHost);
-    IPC_MESSAGE_HANDLER(AppCacheMsg_GetResourceList, OnGetResourceList);
-    IPC_MESSAGE_HANDLER(AppCacheMsg_SelectCache, OnSelectCache);
+    IPC_MESSAGE_HANDLER(AppCacheMsg_RegisterHost, OnRegisterHost)
+    IPC_MESSAGE_HANDLER(AppCacheMsg_UnregisterHost, OnUnregisterHost)
+    IPC_MESSAGE_HANDLER(AppCacheMsg_GetResourceList, OnGetResourceList)
+    IPC_MESSAGE_HANDLER(AppCacheMsg_SelectCache, OnSelectCache)
     IPC_MESSAGE_HANDLER(AppCacheMsg_SelectCacheForWorker,
-                        OnSelectCacheForWorker);
+                        OnSelectCacheForWorker)
     IPC_MESSAGE_HANDLER(AppCacheMsg_SelectCacheForSharedWorker,
-                        OnSelectCacheForSharedWorker);
-    IPC_MESSAGE_HANDLER(AppCacheMsg_MarkAsForeignEntry, OnMarkAsForeignEntry);
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheMsg_GetStatus, OnGetStatus);
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheMsg_StartUpdate, OnStartUpdate);
-    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheMsg_SwapCache, OnSwapCache);
+                        OnSelectCacheForSharedWorker)
+    IPC_MESSAGE_HANDLER(AppCacheMsg_MarkAsForeignEntry, OnMarkAsForeignEntry)
+    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheMsg_GetStatus, OnGetStatus)
+    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheMsg_StartUpdate, OnStartUpdate)
+    IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheMsg_SwapCache, OnSwapCache)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
 
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index e4e1909f46996e81c00ded684f11514accd66fc2..b782c2cf5bbcc51c9e37ec51b3551c3277cd5107 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -358,14 +358,15 @@ void AutomationProvider::OnChannelConnected(int pid) {
     Send(new AutomationMsg_InitialLoadsComplete());
 }
 
-void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
+bool AutomationProvider::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
 #if !defined(OS_MACOSX)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowDrag,
                                     WindowSimulateDrag)
 #endif  // !defined(OS_MACOSX)
     IPC_MESSAGE_HANDLER(AutomationMsg_HandleUnused, HandleUnused)
-    IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig);
+    IPC_MESSAGE_HANDLER(AutomationMsg_SetProxyConfig, SetProxyConfig)
     IPC_MESSAGE_HANDLER(AutomationMsg_PrintAsync, PrintAsync)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Find, HandleFindRequest)
     IPC_MESSAGE_HANDLER(AutomationMsg_OverrideEncoding, OverrideEncoding)
@@ -429,8 +430,9 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
     IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_LoginWithUserAndPass,
                                     LoginWithUserAndPass)
 #endif  // defined(OS_CHROMEOS)
-    IPC_MESSAGE_UNHANDLED(OnUnhandledMessage())
+    IPC_MESSAGE_UNHANDLED(handled = false;OnUnhandledMessage())
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void AutomationProvider::OnUnhandledMessage() {
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 40b9bce083666556574088f481d1de5796aa9a29..4eb6f96d113a00b8d0f0359a64dc6a19dfcc7bd6 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -148,7 +148,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
   // IPC implementations
   virtual bool Send(IPC::Message* msg);
   virtual void OnChannelConnected(int pid);
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
   IPC::Message* reply_message_release() {
diff --git a/chrome/browser/automation/chrome_frame_automation_provider.cc b/chrome/browser/automation/chrome_frame_automation_provider.cc
index 8fb062122baa60bc43bdfdb6ba0fd26652e4fe26..7b699f1725d777a955a3cf192b73228688d9458c 100644
--- a/chrome/browser/automation/chrome_frame_automation_provider.cc
+++ b/chrome/browser/automation/chrome_frame_automation_provider.cc
@@ -12,13 +12,13 @@
 ChromeFrameAutomationProvider::ChromeFrameAutomationProvider(Profile* profile)
     : AutomationProvider(profile) {}
 
-void ChromeFrameAutomationProvider::OnMessageReceived(
+bool ChromeFrameAutomationProvider::OnMessageReceived(
     const IPC::Message& message) {
-  if (IsValidMessage(message.type())) {
-    AutomationProvider::OnMessageReceived(message);
-  } else {
-    OnUnhandledMessage(message);
-  }
+  if (IsValidMessage(message.type()))
+    return AutomationProvider::OnMessageReceived(message);
+
+  OnUnhandledMessage(message);
+  return false;
 }
 
 void ChromeFrameAutomationProvider::OnUnhandledMessage(
diff --git a/chrome/browser/automation/chrome_frame_automation_provider.h b/chrome/browser/automation/chrome_frame_automation_provider.h
index fad6bd84e7372886030d2d0f0172fdc2ea4da4bd..f2a67e0be5f4e76f2c58105e0490005db174f8ef 100644
--- a/chrome/browser/automation/chrome_frame_automation_provider.h
+++ b/chrome/browser/automation/chrome_frame_automation_provider.h
@@ -24,7 +24,7 @@ class ChromeFrameAutomationProvider : public AutomationProvider {
   explicit ChromeFrameAutomationProvider(Profile* profile);
 
   // IPC::Channel::Listener overrides.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
  protected:
   // This function is called when we receive an invalid message type.
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index 78afce109d4622d1092c5ab8d38b237889a6ad30..103225bc091e5b220eb33acb3d1355f39e3bbf23 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -203,8 +203,9 @@ void TestingAutomationProvider::Observe(NotificationType type,
   Release();
 }
 
-void TestingAutomationProvider::OnMessageReceived(
+bool TestingAutomationProvider::OnMessageReceived(
     const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(TestingAutomationProvider, message)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
     IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
@@ -389,8 +390,10 @@ void TestingAutomationProvider::OnMessageReceived(
     IPC_MESSAGE_HANDLER(AutomationMsg_LoadBlockedPlugins, LoadBlockedPlugins)
     IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
 
-    IPC_MESSAGE_UNHANDLED(AutomationProvider::OnMessageReceived(message));
+    IPC_MESSAGE_UNHANDLED(
+        handled = AutomationProvider::OnMessageReceived(message))
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void TestingAutomationProvider::OnChannelError() {
diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h
index 57f95729f6ae0572c1645b5a5cff77f80e0f42c8..6bda672a618b58aafa48e39ed6c62621702fdaa2 100644
--- a/chrome/browser/automation/testing_automation_provider.h
+++ b/chrome/browser/automation/testing_automation_provider.h
@@ -33,7 +33,7 @@ class TestingAutomationProvider : public AutomationProvider,
   virtual void OnBrowserRemoved(const Browser* browser);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
  private:
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 511747bd0460991321686970767fc0cd48b9fcf6..9e374c462b13be474d2aa547a192535c855a4b15 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -132,13 +132,14 @@ bool GpuProcessHost::Send(IPC::Message* msg) {
   return BrowserChildProcessHost::Send(msg);
 }
 
-void GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
+bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) {
   DCHECK(CalledOnValidThread());
 
   if (message.routing_id() == MSG_ROUTING_CONTROL)
-    OnControlMessageReceived(message);
-  else
-    RouteOnUIThread(message);
+    return OnControlMessageReceived(message);
+
+  RouteOnUIThread(message);
+  return true;
 }
 
 void GpuProcessHost::EstablishGpuChannel(int renderer_id,
@@ -178,7 +179,7 @@ GpuProcessHost::SynchronizationRequest::SynchronizationRequest(
 
 GpuProcessHost::SynchronizationRequest::~SynchronizationRequest() {}
 
-void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
+bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
   DCHECK(CalledOnValidThread());
 
   IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message)
@@ -202,6 +203,8 @@ void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
     // handle it.
     IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message))
   IPC_END_MESSAGE_MAP()
+
+  return true;
 }
 
 void GpuProcessHost::OnChannelEstablished(
diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h
index a1b7c8cfde636ada8d1f6fcd811c9e4584da8fc9..14edf88d16f25d453e2d114f5f843b428120184e 100644
--- a/chrome/browser/gpu_process_host.h
+++ b/chrome/browser/gpu_process_host.h
@@ -37,7 +37,7 @@ class GpuProcessHost : public BrowserChildProcessHost, public NonThreadSafe {
   virtual bool Send(IPC::Message* msg);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // Tells the GPU process to create a new channel for communication with a
   // renderer. Will asynchronously send message to object with given routing id
@@ -77,7 +77,7 @@ class GpuProcessHost : public BrowserChildProcessHost, public NonThreadSafe {
   bool EnsureInitialized();
   bool Init();
 
-  void OnControlMessageReceived(const IPC::Message& message);
+  bool OnControlMessageReceived(const IPC::Message& message);
 
   // Message handlers.
   void OnChannelEstablished(const IPC::ChannelHandle& channel_handle,
diff --git a/chrome/browser/gpu_process_host_ui_shim.cc b/chrome/browser/gpu_process_host_ui_shim.cc
index d6b7d6a50280fc91c05f170af0c6d84bd36526d3..87c7be28ff005ea202985f4e6d6d6030058fc2a3 100644
--- a/chrome/browser/gpu_process_host_ui_shim.cc
+++ b/chrome/browser/gpu_process_host_ui_shim.cc
@@ -63,13 +63,13 @@ void GpuProcessHostUIShim::RemoveRoute(int32 routing_id) {
   router_.RemoveRoute(routing_id);
 }
 
-void GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
+bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
   DCHECK(CalledOnValidThread());
 
   if (message.routing_id() == MSG_ROUTING_CONTROL)
-    OnControlMessageReceived(message);
-  else
-    router_.RouteMessage(message);
+    return OnControlMessageReceived(message);
+
+  return router_.RouteMessage(message);
 }
 
 void GpuProcessHostUIShim::CollectGraphicsInfoAsynchronously() {
@@ -119,7 +119,8 @@ void GpuProcessHostUIShim::OnScheduleComposite(int renderer_id,
   }
   host->ScheduleComposite();
 }
-void GpuProcessHostUIShim::OnControlMessageReceived(
+
+bool GpuProcessHostUIShim::OnControlMessageReceived(
     const IPC::Message& message) {
   DCHECK(CalledOnValidThread());
 
@@ -127,9 +128,10 @@ void GpuProcessHostUIShim::OnControlMessageReceived(
     IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
                         OnGraphicsInfoCollected)
 #if defined(OS_WIN)
-    IPC_MESSAGE_HANDLER(GpuHostMsg_ScheduleComposite,
-                        OnScheduleComposite);
+    IPC_MESSAGE_HANDLER(GpuHostMsg_ScheduleComposite, OnScheduleComposite);
 #endif
     IPC_MESSAGE_UNHANDLED_ERROR()
   IPC_END_MESSAGE_MAP()
+
+  return true;
 }
diff --git a/chrome/browser/gpu_process_host_ui_shim.h b/chrome/browser/gpu_process_host_ui_shim.h
index d0d0f37dfe919b70fe2d7e58bf5d6364c8a12bf4..f261093ddbbb5473eb6227ffb816e8e6bc905a2c 100644
--- a/chrome/browser/gpu_process_host_ui_shim.h
+++ b/chrome/browser/gpu_process_host_ui_shim.h
@@ -36,7 +36,7 @@ class GpuProcessHostUIShim : public IPC::Channel::Sender,
   // The GpuProcessHost causes this to be called on the UI thread to
   // dispatch the incoming messages from the GPU process, which are
   // actually received on the IO thread.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // See documentation on MessageRouter for AddRoute and RemoveRoute
   void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
@@ -72,7 +72,7 @@ class GpuProcessHostUIShim : public IPC::Channel::Sender,
   // Message handlers.
   void OnGraphicsInfoCollected(const GPUInfo& gpu_info);
   void OnScheduleComposite(int32 renderer_id, int32 render_view_id);
-  void OnControlMessageReceived(const IPC::Message& message);
+  bool OnControlMessageReceived(const IPC::Message& message);
 
   int last_routing_id_;
 
diff --git a/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc b/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
index ba1b5aa42d9bef2c8a424e9083e0100bff685b2c..15ac4a27975bd169208ddbdf6b0c461a1c5efe39 100644
--- a/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
+++ b/chrome/browser/importer/firefox_importer_unittest_utils_mac.cc
@@ -94,11 +94,14 @@ class FFDecryptorServerChannelListener : public IPC::Channel::Listener {
       sender_->Send(new Msg_Decryptor_Quit());
   }
 
-  virtual void OnMessageReceived(const IPC::Message& msg) {
+  virtual bool OnMessageReceived(const IPC::Message& msg) {
+    bool handled = true;
     IPC_BEGIN_MESSAGE_MAP(FFDecryptorServerChannelListener, msg)
       IPC_MESSAGE_HANDLER(Msg_Decryptor_InitReturnCode, OnInitDecryptorResponse)
       IPC_MESSAGE_HANDLER(Msg_Decryptor_Response, OnDecryptedTextResonse)
+      IPC_MESSAGE_UNHANDLED(handled = false)
     IPC_END_MESSAGE_MAP()
+    return handled;
   }
 
   // If an error occured, just kill the message Loop.
@@ -231,12 +234,15 @@ class FFDecryptorClientChannelListener : public IPC::Channel::Listener {
     MessageLoop::current()->Quit();
   }
 
-  virtual void OnMessageReceived(const IPC::Message& msg) {
+  virtual bool OnMessageReceived(const IPC::Message& msg) {
+    bool handled = true;
     IPC_BEGIN_MESSAGE_MAP(FFDecryptorClientChannelListener, msg)
       IPC_MESSAGE_HANDLER(Msg_Decryptor_Init, OnDecryptor_Init)
       IPC_MESSAGE_HANDLER(Msg_Decrypt, OnDecrypt)
       IPC_MESSAGE_HANDLER(Msg_Decryptor_Quit, OnQuitRequest)
+      IPC_MESSAGE_UNHANDLED(handled = false)
     IPC_END_MESSAGE_MAP()
+    return handled;
   }
 
   virtual void OnChannelError() {
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.cc b/chrome/browser/nacl_host/nacl_broker_host_win.cc
index 0942a23f70542bdaa42dd55798b52220f0e45d35..7d0fbeab355d25ddf98c1a9ec9fbd57fc9e7c183 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.cc
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.cc
@@ -46,10 +46,13 @@ bool NaClBrokerHost::Init() {
   return true;
 }
 
-void NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) {
+bool NaClBrokerHost::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(NaClBrokerHost, msg)
     IPC_MESSAGE_HANDLER(NaClProcessMsg_LoaderLaunched, OnLoaderLaunched)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 bool NaClBrokerHost::LaunchLoader(
diff --git a/chrome/browser/nacl_host/nacl_broker_host_win.h b/chrome/browser/nacl_host/nacl_broker_host_win.h
index 7213ff0d3c0cbb81e88ae05bede54efba9372ed7..27ceb2488ab9ca309679a881f96d12d8bfe7181c 100644
--- a/chrome/browser/nacl_host/nacl_broker_host_win.h
+++ b/chrome/browser/nacl_host/nacl_broker_host_win.h
@@ -33,7 +33,7 @@ class NaClBrokerHost : public BrowserChildProcessHost {
                         base::ProcessHandle handle);
 
   // IPC::Channel::Listener
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   bool stopping_;
 
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index f9f56678f6d3799e42757799b33c1e34b36d9999..a0097023522618d2daa1a0d084a1900101880a74 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -282,8 +282,9 @@ void NaClProcessHost::SendStartMessage() {
   sockets_for_sel_ldr_.clear();
 }
 
-void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
+bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
   NOTREACHED() << "Invalid message with type = " << msg.type();
+  return false;
 }
 
 bool NaClProcessHost::CanShutdown() {
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index e2b0c39e2b427bdf872cf8ed26569ba7200bf485..c0d57312a61c105a309d44932721b8b8a7da0173 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -32,7 +32,7 @@ class NaClProcessHost : public BrowserChildProcessHost {
               int socket_count,
               IPC::Message* reply_msg);
 
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   void OnProcessLaunchedByBroker(base::ProcessHandle handle);
 
diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc
index fd7d9bd21280f0bf9c5085192cc1668de3be8cde..2baf0d0452ba6c60c92703bde6e5d6fc89b56bd1 100644
--- a/chrome/browser/plugin_data_remover.cc
+++ b/chrome/browser/plugin_data_remover.cc
@@ -115,12 +115,14 @@ void PluginDataRemover::OnTimeout() {
   SignalDone();
 }
 
-void PluginDataRemover::OnMessageReceived(const IPC::Message& msg) {
+bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) {
   IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg)
     IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult,
                         OnClearSiteDataResult)
     IPC_MESSAGE_UNHANDLED_ERROR()
   IPC_END_MESSAGE_MAP()
+
+  return true;
 }
 
 void PluginDataRemover::OnChannelError() {
diff --git a/chrome/browser/plugin_data_remover.h b/chrome/browser/plugin_data_remover.h
index 58387fe4d21730fbe42c7f6b99446e532215641d..77f7f582dbcfccef92c8d2128c763bb01b878b04 100644
--- a/chrome/browser/plugin_data_remover.h
+++ b/chrome/browser/plugin_data_remover.h
@@ -45,8 +45,8 @@ class PluginDataRemover : public base::RefCountedThreadSafe<PluginDataRemover>,
   virtual void OnChannelOpened(const IPC::ChannelHandle& handle);
   virtual void OnError();
 
-  // IPC::ChannelProxy::MessageFilter methods
-  virtual void OnMessageReceived(const IPC::Message& message);
+  // IPC::Channel::Listener methods
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelError();
 
  private:
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index 4be2ce78396676c1d5c5e8e4994f1cf8146c11b6..cb99a80c8539a568437b8d09edec5f3d6a1057a0 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -298,7 +298,8 @@ void PluginProcessHost::OnProcessLaunched() {
   }
 }
 
-void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
+bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg)
     IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated)
     IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetPluginFinderUrl,
@@ -327,8 +328,11 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginSetCursorVisibility,
                         OnPluginSetCursorVisibility)
 #endif
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+
+  DCHECK(handled);
+  return handled;
 }
 
 void PluginProcessHost::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index b98840ef5af4fe1124c81d76d25aacd41ecaedec..d30a77aaf1dce6e4f73a4221bbf016cdb0fae1bb 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -66,7 +66,7 @@ class PluginProcessHost : public BrowserChildProcessHost,
   // Force the plugin process to shutdown (cleanly).
   virtual void ForceShutdown();
 
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/browser/ppapi_plugin_process_host.cc b/chrome/browser/ppapi_plugin_process_host.cc
index b9be47ac65224c7eaa7de895563f3bbac76a0c5b..c90d1f4eda982bce7bfb8968c6e73db520b33444 100644
--- a/chrome/browser/ppapi_plugin_process_host.cc
+++ b/chrome/browser/ppapi_plugin_process_host.cc
@@ -69,11 +69,14 @@ bool PpapiPluginProcessHost::CanShutdown() {
 void PpapiPluginProcessHost::OnProcessLaunched() {
 }
 
-void PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
+bool PpapiPluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PpapiPluginProcessHost, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PluginLoaded, OnPluginLoaded)
-    IPC_MESSAGE_UNHANDLED_ERROR();
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void PpapiPluginProcessHost::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/browser/ppapi_plugin_process_host.h b/chrome/browser/ppapi_plugin_process_host.h
index 23be5dac83b096d878eba9e2dd491f847f2245eb..227cf31e0911cd06b57d4c8bd3ab92417ae913b9 100644
--- a/chrome/browser/ppapi_plugin_process_host.h
+++ b/chrome/browser/ppapi_plugin_process_host.h
@@ -23,7 +23,7 @@ class PpapiPluginProcessHost : public BrowserChildProcessHost {
   virtual bool CanShutdown();
   virtual void OnProcessLaunched();
 
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/browser/profile_import_process_host.cc b/chrome/browser/profile_import_process_host.cc
index d221817f458b56a7f827b89aecf3c27c63594bf7..3663ef7f45ffda18fdf25a861fb80a4387a2433e 100644
--- a/chrome/browser/profile_import_process_host.cc
+++ b/chrome/browser/profile_import_process_host.cc
@@ -118,13 +118,14 @@ bool ProfileImportProcessHost::StartProcess() {
   return true;
 }
 
-void ProfileImportProcessHost::OnMessageReceived(const IPC::Message& message) {
+bool ProfileImportProcessHost::OnMessageReceived(const IPC::Message& message) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   BrowserThread::PostTask(
       thread_id_, FROM_HERE,
       NewRunnableMethod(import_process_client_.get(),
                         &ImportProcessClient::OnMessageReceived,
                         message));
+  return true;
 }
 
 void ProfileImportProcessHost::OnProcessCrashed(int exit_code) {
@@ -144,8 +145,9 @@ ProfileImportProcessHost::ImportProcessClient::ImportProcessClient() {}
 
 ProfileImportProcessHost::ImportProcessClient::~ImportProcessClient() {}
 
-void ProfileImportProcessHost::ImportProcessClient::OnMessageReceived(
+bool ProfileImportProcessHost::ImportProcessClient::OnMessageReceived(
     const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ProfileImportProcessHost, message)
     // Notification messages about the state of the import process.
     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_Import_Started,
@@ -176,5 +178,7 @@ void ProfileImportProcessHost::ImportProcessClient::OnMessageReceived(
                         ImportProcessClient::OnPasswordFormImportReady)
     IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyKeywordsReady,
                         ImportProcessClient::OnKeywordsImportReady)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
+  return handled;
 }
diff --git a/chrome/browser/profile_import_process_host.h b/chrome/browser/profile_import_process_host.h
index 68ef64fe14fa4eb1bf397a84a49f63d0bf4823ab..dae610869bf846a8e734927899fde68a0f34b6e6 100644
--- a/chrome/browser/profile_import_process_host.h
+++ b/chrome/browser/profile_import_process_host.h
@@ -73,7 +73,7 @@ class ProfileImportProcessHost : public BrowserChildProcessHost {
         const std::vector<TemplateURL>& template_urls,
             int default_keyword_index, bool unique_on_host_and_path) {}
 
-    virtual void OnMessageReceived(const IPC::Message& message);
+    virtual bool OnMessageReceived(const IPC::Message& message);
 
    protected:
     friend class base::RefCountedThreadSafe<ImportProcessClient>;
@@ -122,7 +122,7 @@ class ProfileImportProcessHost : public BrowserChildProcessHost {
 
   // Called by the external importer process to send messages back to the
   // ImportProcessClient.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // Overridden from BrowserChildProcessHost:
   virtual void OnProcessCrashed(int exit_code);
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index 66968b75a0fddc0636a205eb077d19b560ad3387..e3849fbcaa1fffc417725962874b051ead5f8bb0 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -977,11 +977,11 @@ bool BrowserRenderProcessHost::Send(IPC::Message* msg) {
   return channel_->Send(msg);
 }
 
-void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
+bool BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
   // If we're about to be deleted, we can no longer trust that our profile is
   // valid, so we ignore incoming messages.
   if (deleting_soon_)
-    return;
+    return false;
 
 #if defined(OS_CHROMEOS)
   // To troubleshoot crosbug.com/7327.
@@ -1018,7 +1018,7 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
       UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_BRPH"));
       ReceivedBadMessage();
     }
-    return;
+    return true;
   }
 
   // Dispatch incoming messages to the appropriate RenderView/WidgetHost.
@@ -1031,9 +1031,9 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
       reply->set_reply_error();
       Send(reply);
     }
-    return;
+    return true;
   }
-  listener->OnMessageReceived(msg);
+  return listener->OnMessageReceived(msg);
 }
 
 void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h
index 3b28e6b378d7d2af564ba8f59870a03824f5bdd7..f1bc47a708ef4dd8641c87d93cf40eeaa8f603d8 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.h
+++ b/chrome/browser/renderer_host/browser_render_process_host.h
@@ -85,7 +85,7 @@ class BrowserRenderProcessHost : public RenderProcessHost,
   virtual bool Send(IPC::Message* msg);
 
   // IPC::Channel::Listener via RenderProcessHost.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/browser/renderer_host/mock_render_process_host.cc b/chrome/browser/renderer_host/mock_render_process_host.cc
index bd4d675fb00e5cda57d1a1559a8834f60c4b8b19..1f1a2b3fbb875a34e72c6957e761e28084705790 100644
--- a/chrome/browser/renderer_host/mock_render_process_host.cc
+++ b/chrome/browser/renderer_host/mock_render_process_host.cc
@@ -117,7 +117,8 @@ TransportDIB* MockRenderProcessHost::GetTransportDIB(TransportDIB::Id dib_id) {
   return transport_dib_;
 }
 
-void MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
+bool MockRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
+  return false;
 }
 
 void MockRenderProcessHost::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/browser/renderer_host/mock_render_process_host.h b/chrome/browser/renderer_host/mock_render_process_host.h
index 0d8bfa61057d7b58b2cc2752085221d8e8211f7b..6309685c150d967d9c1f8214531062ecc643d16f 100644
--- a/chrome/browser/renderer_host/mock_render_process_host.h
+++ b/chrome/browser/renderer_host/mock_render_process_host.h
@@ -59,7 +59,7 @@ class MockRenderProcessHost : public RenderProcessHost {
   virtual bool Send(IPC::Message* msg);
 
   // IPC::Channel::Listener via RenderProcessHost.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
 
   // Attaches the factory object so we can remove this object in its destructor
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index df012bf105b2e57410fa0258156291c839d11136..950c60eeef5191cdad9326d41686e1225c90d654 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -738,7 +738,7 @@ bool RenderViewHost::SuddenTerminationAllowed() const {
 ///////////////////////////////////////////////////////////////////////////////
 // RenderViewHost, IPC message handlers:
 
-void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
+bool RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
 #if defined(OS_WIN)
   // On Windows there's a potential deadlock with sync messsages going in
   // a circle from browser -> plugin -> renderer -> browser.
@@ -756,10 +756,11 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
     IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
     reply->set_reply_error();
     Send(reply);
-    return;
+    return true;
   }
 #endif
 
+  bool handled = true;
   bool msg_is_ok = true;
   IPC_BEGIN_MESSAGE_MAP_EX(RenderViewHost, msg, msg_is_ok)
     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowView, OnMsgShowView)
@@ -917,7 +918,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(ViewHostMsg_PagesReadyForPreview,
                         OnPagesReadyForPreview)
     // Have the super handle all other messages.
-    IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg))
+    IPC_MESSAGE_UNHANDLED(handled = RenderWidgetHost::OnMessageReceived(msg))
   IPC_END_MESSAGE_MAP_EX()
 
   if (!msg_is_ok) {
@@ -926,6 +927,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
     UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_RVH"));
     process()->ReceivedBadMessage();
   }
+
+  return handled;
 }
 
 void RenderViewHost::Shutdown() {
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 163039b80c91aa66fc09188a5aab9d8f86a2f069..02c08d17839beea7268ee9359535a8e7ecb2cf23 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -446,7 +446,7 @@ class RenderViewHost : public RenderWidgetHost {
   // RenderWidgetHost public overrides.
   virtual void Shutdown();
   virtual bool IsRenderView() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void GotFocus();
   virtual void LostCapture();
   virtual void ForwardMouseEvent(const WebKit::WebMouseEvent& mouse_event);
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 3c319e033c61b335329921e0641c4aa07191cece..28862af285e633a3ea54c399a3866d72a8860aef 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -151,7 +151,8 @@ bool RenderWidgetHost::IsRenderView() const {
   return false;
 }
 
-void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
+bool RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
+  bool handled = true;
   bool msg_is_ok = true;
   IPC_BEGIN_MESSAGE_MAP_EX(RenderWidgetHost, msg, msg_is_ok)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady)
@@ -192,7 +193,7 @@ void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
     IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
                         OnMsgDestroyPluginContainer)
 #endif
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
 
   if (!msg_is_ok) {
@@ -200,6 +201,7 @@ void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) {
     UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_RWH"));
     process()->ReceivedBadMessage();
   }
+  return handled;
 }
 
 bool RenderWidgetHost::Send(IPC::Message* msg) {
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index 90204aa36eee52fa27e5909571fda1b4a6f5e393..73d7fa4c265d8ead43de4c84bdcd5c6654d61d3f 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -181,7 +181,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
   virtual bool IsRenderView() const;
 
   // IPC::Channel::Listener
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // Sends a message to the corresponding object in the renderer.
   virtual bool Send(IPC::Message* msg);
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.cc b/chrome/browser/renderer_host/test/test_render_view_host.cc
index 72674497fb0baa378f5705ca14d5f764e78be315..1c2e4b415256bfeb9bba1b9f1089b4936de96ad1 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.cc
+++ b/chrome/browser/renderer_host/test/test_render_view_host.cc
@@ -70,8 +70,8 @@ bool TestRenderViewHost::IsRenderViewLive() const {
   return render_view_created_;
 }
 
-void TestRenderViewHost::TestOnMessageReceived(const IPC::Message& msg) {
-  OnMessageReceived(msg);
+bool TestRenderViewHost::TestOnMessageReceived(const IPC::Message& msg) {
+  return OnMessageReceived(msg);
 }
 
 void TestRenderViewHost::SendNavigate(int page_id, const GURL& url) {
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index f84bc21fb19065e89a432ad5b6f13875651a1167..70f2d1185fd7ae7a8cf2d73b4ca6df55012b4227 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -166,7 +166,7 @@ class TestRenderViewHost : public RenderViewHost {
 
   // Calls the RenderViewHosts' private OnMessageReceived function with the
   // given message.
-  void TestOnMessageReceived(const IPC::Message& msg);
+  bool TestOnMessageReceived(const IPC::Message& msg);
 
   // Calls OnMsgNavigate on the RenderViewHost with the given information,
   // setting the rest of the parameters in the message to the "typical" values.
diff --git a/chrome/browser/service/service_process_control.cc b/chrome/browser/service/service_process_control.cc
index dfba80a22ab93bea45b4de59ce34867ac5bbe4dd..27e3a2dcdb7eb167985c87110e929192ee07e5ac 100644
--- a/chrome/browser/service/service_process_control.cc
+++ b/chrome/browser/service/service_process_control.cc
@@ -238,14 +238,17 @@ void ServiceProcessControl::OnProcessLaunched() {
   launcher_ = NULL;
 }
 
-void ServiceProcessControl::OnMessageReceived(const IPC::Message& message) {
+bool ServiceProcessControl::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;;
   IPC_BEGIN_MESSAGE_MAP(ServiceProcessControl, message)
-      IPC_MESSAGE_HANDLER(ServiceHostMsg_GoodDay, OnGoodDay)
-      IPC_MESSAGE_HANDLER(ServiceHostMsg_CloudPrintProxy_IsEnabled,
-                          OnCloudPrintProxyIsEnabled)
-      IPC_MESSAGE_HANDLER(ServiceHostMsg_RemotingHost_HostInfo,
-                          OnRemotingHostInfo)
+    IPC_MESSAGE_HANDLER(ServiceHostMsg_GoodDay, OnGoodDay)
+    IPC_MESSAGE_HANDLER(ServiceHostMsg_CloudPrintProxy_IsEnabled,
+                        OnCloudPrintProxyIsEnabled)
+    IPC_MESSAGE_HANDLER(ServiceHostMsg_RemotingHost_HostInfo,
+                         OnRemotingHostInfo)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void ServiceProcessControl::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/browser/service/service_process_control.h b/chrome/browser/service/service_process_control.h
index efbd545bfe41cc8be18b58fea56525432853f94c..9162736f4a8fd633a47c36e543e399dbd2b23010 100644
--- a/chrome/browser/service/service_process_control.h
+++ b/chrome/browser/service/service_process_control.h
@@ -77,7 +77,7 @@ class ServiceProcessControl : public IPC::Channel::Sender,
   void Launch(Task* success_task, Task* failure_task);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/browser/utility_process_host.cc b/chrome/browser/utility_process_host.cc
index ab5b39f363cd5cb4920bb08392219bfc5bd5861c..4d208fd10766220f3b98716a74821b5b4cc89cc9 100644
--- a/chrome/browser/utility_process_host.cc
+++ b/chrome/browser/utility_process_host.cc
@@ -153,10 +153,11 @@ bool UtilityProcessHost::StartProcess(const FilePath& exposed_dir) {
   return true;
 }
 
-void UtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
+bool UtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
   BrowserThread::PostTask(
       client_thread_id_, FROM_HERE,
       NewRunnableMethod(client_.get(), &Client::OnMessageReceived, message));
+  return true;
 }
 
 void UtilityProcessHost::OnProcessCrashed(int exit_code) {
@@ -169,8 +170,9 @@ bool UtilityProcessHost::CanShutdown() {
   return true;
 }
 
-void UtilityProcessHost::Client::OnMessageReceived(
+bool UtilityProcessHost::Client::OnMessageReceived(
     const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(UtilityProcessHost, message)
     IPC_MESSAGE_HANDLER(UtilityHostMsg_UnpackExtension_Succeeded,
                         Client::OnUnpackExtensionSucceeded)
@@ -192,5 +194,7 @@ void UtilityProcessHost::Client::OnMessageReceived(
                         Client::OnIDBKeysFromValuesAndKeyPathSucceeded)
     IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Failed,
                         Client::OnIDBKeysFromValuesAndKeyPathFailed)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
+  return handled;
 }
diff --git a/chrome/browser/utility_process_host.h b/chrome/browser/utility_process_host.h
index 21776b6d954823778f73e860e2f6c289868e51af..c1f4055baf666c8d7d781e79278301c5db956b82 100644
--- a/chrome/browser/utility_process_host.h
+++ b/chrome/browser/utility_process_host.h
@@ -97,7 +97,7 @@ class UtilityProcessHost : public BrowserChildProcessHost {
    private:
     friend class UtilityProcessHost;
 
-    void OnMessageReceived(const IPC::Message& message);
+    bool OnMessageReceived(const IPC::Message& message);
 
     DISALLOW_COPY_AND_ASSIGN(Client);
   };
@@ -149,7 +149,7 @@ class UtilityProcessHost : public BrowserChildProcessHost {
   bool StartProcess(const FilePath& exposed_dir);
 
   // IPC messages:
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // BrowserChildProcessHost:
   virtual void OnProcessCrashed(int exit_code);
diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc
index 61671322db5c464214fe6bd3d2fdfbf3b3c2c4e7..2006e2f3b961536344455ed4e3bd0e41d6180edc 100644
--- a/chrome/browser/worker_host/worker_process_host.cc
+++ b/chrome/browser/worker_host/worker_process_host.cc
@@ -276,7 +276,7 @@ bool WorkerProcessHost::FilterMessage(const IPC::Message& message,
 void WorkerProcessHost::OnProcessLaunched() {
 }
 
-void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
+bool WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
   bool msg_is_ok = true;
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP_EX(WorkerProcessHost, message, msg_is_ok)
@@ -293,7 +293,7 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
   }
 
   if (handled)
-    return;
+    return true;
 
   for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) {
     if (i->worker_route_id() == message.routing_id()) {
@@ -308,9 +308,10 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
         instances_.erase(i);
         UpdateTitle();
       }
-      break;
+      return true;
     }
   }
+  return false;
 }
 
 // Sent to notify the browser process when a worker context invokes close(), so
diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h
index 150da935c8858712086aeb59bfbe428f640c3d6b..f3f6fddf5895a6e5df2e147ca76bb12806e86700 100644
--- a/chrome/browser/worker_host/worker_process_host.h
+++ b/chrome/browser/worker_host/worker_process_host.h
@@ -149,7 +149,7 @@ class WorkerProcessHost : public BrowserChildProcessHost {
 
   // IPC::Channel::Listener implementation:
   // Called when a message arrives from the worker process.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   void OnWorkerContextClosed(int worker_route_id);
   void OnAllowDatabase(int worker_route_id,
diff --git a/chrome/common/appcache/appcache_dispatcher.h b/chrome/common/appcache/appcache_dispatcher.h
index f09918302a3f5d73240040a31610ecbf4bf747cc..f88a38a790b5fb1f49bf6e76a1eb2da8381b0d68 100644
--- a/chrome/common/appcache/appcache_dispatcher.h
+++ b/chrome/common/appcache/appcache_dispatcher.h
@@ -9,20 +9,21 @@
 #include <string>
 #include <vector>
 #include "chrome/common/appcache/appcache_backend_proxy.h"
-#include "ipc/ipc_message.h"
+#include "ipc/ipc_channel.h"
 #include "webkit/appcache/appcache_frontend_impl.h"
 
 // Dispatches appcache related messages sent to a child process from the
 // main browser process. There is one instance per child process. Messages
 // are dispatched on the main child thread. The ChildThread base class
 // creates an instance and delegates calls to it.
-class AppCacheDispatcher {
+class AppCacheDispatcher : public IPC::Channel::Listener {
  public:
   explicit AppCacheDispatcher(IPC::Message::Sender* sender)
       : backend_proxy_(sender) {}
 
   AppCacheBackendProxy* backend_proxy() { return &backend_proxy_; }
 
+  // IPC::Channel::Listener implementation
   bool OnMessageReceived(const IPC::Message& msg);
 
  private:
diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc
index c19d0ca610a12562c393d96b2bfa5bd18a59b79e..e03b3a6d1cac634d8e0f32f2c015416e84f353d8 100644
--- a/chrome/common/child_process_host.cc
+++ b/chrome/common/child_process_host.cc
@@ -155,13 +155,13 @@ ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host)
     : host_(host) {
 }
 
-void ChildProcessHost::ListenerHook::OnMessageReceived(
+bool ChildProcessHost::ListenerHook::OnMessageReceived(
     const IPC::Message& msg) {
 #ifdef IPC_MESSAGE_LOG_ENABLED
   IPC::Logging* logger = IPC::Logging::GetInstance();
   if (msg.type() == IPC_LOGGING_ID) {
     logger->OnReceivedLoggingMessage(msg);
-    return;
+    return true;
   }
 
   if (logger->Enabled())
@@ -183,12 +183,13 @@ void ChildProcessHost::ListenerHook::OnMessageReceived(
   }
 
   if (!handled)
-    host_->OnMessageReceived(msg);
+    handled = host_->OnMessageReceived(msg);
 
 #ifdef IPC_MESSAGE_LOG_ENABLED
   if (logger->Enabled())
     logger->OnPostDispatchMessage(msg, host_->channel_id_);
 #endif
+  return handled;
 }
 
 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/common/child_process_host.h b/chrome/common/child_process_host.h
index 3b467eca0ff2a106087e01b65fb49abc1e5c0465..c8223468961ab01d9d710105a178d8c4ddfdfc1f 100644
--- a/chrome/common/child_process_host.h
+++ b/chrome/common/child_process_host.h
@@ -80,7 +80,7 @@ class ChildProcessHost : public IPC::Channel::Listener,
   virtual void InstanceCreated();
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg) { }
+  virtual bool OnMessageReceived(const IPC::Message& msg) { return false; }
   virtual void OnChannelConnected(int32 peer_pid) { }
   virtual void OnChannelError() { }
 
@@ -102,7 +102,7 @@ class ChildProcessHost : public IPC::Channel::Listener,
   class ListenerHook : public IPC::Channel::Listener {
    public:
     explicit ListenerHook(ChildProcessHost* host);
-    virtual void OnMessageReceived(const IPC::Message& msg);
+    virtual bool OnMessageReceived(const IPC::Message& msg);
     virtual void OnChannelConnected(int32 peer_pid);
     virtual void OnChannelError();
    private:
diff --git a/chrome/common/child_thread.cc b/chrome/common/child_thread.cc
index 2a46de8599a01bc4ab083886b2824d14f7eae55f..53823bcdb154d928613471f1d6239144af420f13 100644
--- a/chrome/common/child_thread.cc
+++ b/chrome/common/child_thread.cc
@@ -139,14 +139,14 @@ MessageLoop* ChildThread::message_loop() {
   return message_loop_;
 }
 
-void ChildThread::OnMessageReceived(const IPC::Message& msg) {
+bool ChildThread::OnMessageReceived(const IPC::Message& msg) {
   // Resource responses are sent to the resource dispatcher.
   if (resource_dispatcher_->OnMessageReceived(msg))
-    return;
+    return true;
   if (socket_stream_dispatcher_->OnMessageReceived(msg))
-    return;
+    return true;
   if (file_system_dispatcher_->OnMessageReceived(msg))
-    return;
+    return true;
 
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ChildThread, msg)
@@ -160,13 +160,12 @@ void ChildThread::OnMessageReceived(const IPC::Message& msg) {
   IPC_END_MESSAGE_MAP()
 
   if (handled)
-    return;
+    return true;
 
-  if (msg.routing_id() == MSG_ROUTING_CONTROL) {
-    OnControlMessageReceived(msg);
-  } else {
-    router_.OnMessageReceived(msg);
-  }
+  if (msg.routing_id() == MSG_ROUTING_CONTROL)
+    return OnControlMessageReceived(msg);
+
+  return router_.OnMessageReceived(msg);
 }
 
 void ChildThread::OnAskBeforeShutdown() {
diff --git a/chrome/common/child_thread.h b/chrome/common/child_thread.h
index 337a7f8ac1ea4328bf8c2008823df4b3430e763d..dbe86778679d3ccd40f44f336cdd90d5a8a926a2 100644
--- a/chrome/common/child_thread.h
+++ b/chrome/common/child_thread.h
@@ -74,7 +74,9 @@ class ChildThread : public IPC::Channel::Listener,
   // Called when the process refcount is 0.
   void OnProcessFinalRelease();
 
-  virtual void OnControlMessageReceived(const IPC::Message& msg) { }
+  virtual bool OnControlMessageReceived(const IPC::Message& msg) {
+    return false;
+  }
   virtual void OnAskBeforeShutdown();
   virtual void OnShutdown();
 
@@ -92,7 +94,7 @@ class ChildThread : public IPC::Channel::Listener,
   void Init();
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
   std::string channel_name_;
diff --git a/chrome/common/file_system/file_system_dispatcher.h b/chrome/common/file_system/file_system_dispatcher.h
index b8ffb2c334530f3376e0cc4572909d285a5a6195..21bc7924d94bf785e431a13502f7ddfe0d0509e5 100644
--- a/chrome/common/file_system/file_system_dispatcher.h
+++ b/chrome/common/file_system/file_system_dispatcher.h
@@ -25,11 +25,12 @@ class GURL;
 // Dispatches and sends file system related messages sent to/from a child
 // process from/to the main browser process.  There is one instance
 // per child process.  Messages are dispatched on the main child thread.
-class FileSystemDispatcher {
+class FileSystemDispatcher : public IPC::Channel::Listener {
  public:
   FileSystemDispatcher();
   ~FileSystemDispatcher();
 
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& msg);
 
   bool OpenFileSystem(const GURL& origin_url,
diff --git a/chrome/common/message_router.cc b/chrome/common/message_router.cc
index 6bd6e95792b4a41d198b1e46c8ac1a94240cbfda..b3ea5960d47cf1f9eeb15d7f8b6bce7b13731858 100644
--- a/chrome/common/message_router.cc
+++ b/chrome/common/message_router.cc
@@ -10,9 +10,10 @@ MessageRouter::MessageRouter() {
 MessageRouter::~MessageRouter() {
 }
 
-void MessageRouter::OnControlMessageReceived(const IPC::Message& msg) {
+bool MessageRouter::OnControlMessageReceived(const IPC::Message& msg) {
   NOTREACHED() <<
       "should override in subclass if you care about control messages";
+  return false;
 }
 
 bool MessageRouter::Send(IPC::Message* msg) {
@@ -30,12 +31,11 @@ void MessageRouter::RemoveRoute(int32 routing_id) {
   routes_.Remove(routing_id);
 }
 
-void MessageRouter::OnMessageReceived(const IPC::Message& msg) {
-  if (msg.routing_id() == MSG_ROUTING_CONTROL) {
-    OnControlMessageReceived(msg);
-  } else {
-    RouteMessage(msg);
-  }
+bool MessageRouter::OnMessageReceived(const IPC::Message& msg) {
+  if (msg.routing_id() == MSG_ROUTING_CONTROL)
+    return OnControlMessageReceived(msg);
+
+  return RouteMessage(msg);
 }
 
 bool MessageRouter::RouteMessage(const IPC::Message& msg) {
diff --git a/chrome/common/message_router.h b/chrome/common/message_router.h
index 6a610914977ef7a75206c92b981701782645275c..e6709beb4a50ff7f4edfe89e2bb98b095180350c 100644
--- a/chrome/common/message_router.h
+++ b/chrome/common/message_router.h
@@ -34,10 +34,10 @@ class MessageRouter : public IPC::Channel::Listener,
   virtual ~MessageRouter();
 
   // Implemented by subclasses to handle control messages
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // Like OnMessageReceived, except it only handles routed messages.  Returns
   // true if the message was dispatched, or false if there was no listener for
diff --git a/chrome/common/resource_dispatcher.h b/chrome/common/resource_dispatcher.h
index 3ca3492ef65a03eb21178198431d65aa92e6b6ff..52c6589c72d4186e6f53176a42d1ba7c66deed14 100644
--- a/chrome/common/resource_dispatcher.h
+++ b/chrome/common/resource_dispatcher.h
@@ -23,13 +23,12 @@ struct ResourceResponseHead;
 // This class serves as a communication interface between the
 // ResourceDispatcherHost in the browser process and the ResourceLoaderBridge in
 // the child process.  It can be used from any child process.
-class ResourceDispatcher {
+class ResourceDispatcher : public IPC::Channel::Listener {
  public:
   explicit ResourceDispatcher(IPC::Message::Sender* sender);
   ~ResourceDispatcher();
 
-  // Called to possibly handle the incoming IPC message.  Returns true if
-  // handled, else false.
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& message);
 
   // Creates a ResourceLoaderBridge for this type of dispatcher, this is so
diff --git a/chrome/common/socket_stream_dispatcher.h b/chrome/common/socket_stream_dispatcher.h
index e0bf58fc92fb8cc085171174530e174a75fb0ae9..01c5421809d3a4c2731fb7a4a281d296c60823ce 100644
--- a/chrome/common/socket_stream_dispatcher.h
+++ b/chrome/common/socket_stream_dispatcher.h
@@ -9,10 +9,7 @@
 #include <vector>
 
 #include "base/basictypes.h"
-
-namespace IPC {
-class Message;
-}
+#include "ipc/ipc_channel.h"
 
 namespace WebKit {
 class WebSocketStreamHandle;
@@ -27,7 +24,7 @@ class WebSocketStreamHandleDelegate;
 // main browser process.  There is one instance per child process.  Messages
 // are dispatched on the main child thread.  The RenderThread class
 // creates an instance of SocketStreamDispatcher and delegates calls to it.
-class SocketStreamDispatcher {
+class SocketStreamDispatcher : public IPC::Channel::Listener {
  public:
   SocketStreamDispatcher();
   ~SocketStreamDispatcher() {}
@@ -35,6 +32,8 @@ class SocketStreamDispatcher {
   static webkit_glue::WebSocketStreamHandleBridge* CreateBridge(
       WebKit::WebSocketStreamHandle* handle,
       webkit_glue::WebSocketStreamHandleDelegate* delegate);
+
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& msg);
 
  private:
diff --git a/chrome/common/webmessageportchannel_impl.cc b/chrome/common/webmessageportchannel_impl.cc
index b7a938888214908f88ee781a44dbe178ed77233b..077887168806e700c29df623e37d044d0d97dd38 100644
--- a/chrome/common/webmessageportchannel_impl.cc
+++ b/chrome/common/webmessageportchannel_impl.cc
@@ -180,11 +180,14 @@ void WebMessagePortChannelImpl::Send(IPC::Message* message) {
   ChildThread::current()->Send(message);
 }
 
-void WebMessagePortChannelImpl::OnMessageReceived(const IPC::Message& message) {
+bool WebMessagePortChannelImpl::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebMessagePortChannelImpl, message)
     IPC_MESSAGE_HANDLER(WorkerProcessMsg_Message, OnMessage)
     IPC_MESSAGE_HANDLER(WorkerProcessMsg_MessagesQueued, OnMessagedQueued)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void WebMessagePortChannelImpl::OnMessage(
diff --git a/chrome/common/webmessageportchannel_impl.h b/chrome/common/webmessageportchannel_impl.h
index 3c96fc382bd38532740cf1cf21e89d0e4449ee64..0199ebba180d8646c0a308932e7f6ba5ae2d3cc3 100644
--- a/chrome/common/webmessageportchannel_impl.h
+++ b/chrome/common/webmessageportchannel_impl.h
@@ -48,7 +48,7 @@ class WebMessagePortChannelImpl
   void Send(IPC::Message* message);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   void OnMessage(const string16& message,
                  const std::vector<int>& sent_message_port_ids,
diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc
index 8fb5024af6c548108a517db099b2edbf280942a7..79e9186923c72218112399084317b55bac87ffe0 100644
--- a/chrome/gpu/gpu_channel.cc
+++ b/chrome/gpu/gpu_channel.cc
@@ -38,19 +38,18 @@ void GpuChannel::OnChannelConnected(int32 peer_pid) {
   }
 }
 
-void GpuChannel::OnMessageReceived(const IPC::Message& message) {
+bool GpuChannel::OnMessageReceived(const IPC::Message& message) {
   if (log_messages_) {
     VLOG(1) << "received message @" << &message << " on channel @" << this
             << " with type " << message.type();
   }
 
-  if (message.routing_id() == MSG_ROUTING_CONTROL) {
-    OnControlMessageReceived(message);
-  } else {
-    // Fail silently if the GPU process has destroyed while the IPC message was
-    // en-route.
-    router_.RouteMessage(message);
-  }
+  if (message.routing_id() == MSG_ROUTING_CONTROL)
+    return OnControlMessageReceived(message);
+
+  // Fail silently if the GPU process has destroyed while the IPC message was
+  // en-route.
+  return router_.RouteMessage(message);
 }
 
 void GpuChannel::OnChannelError() {
@@ -94,7 +93,8 @@ bool GpuChannel::IsRenderViewGone(int32 renderer_route_id) {
 }
 #endif
 
-void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
+bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg)
     IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateViewCommandBuffer,
         OnCreateViewCommandBuffer)
@@ -106,8 +106,10 @@ void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
         OnCreateVideoDecoder)
     IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoDecoder,
         OnDestroyVideoDecoder)
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 int GpuChannel::GenerateRouteID() {
diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h
index e449dc4b5d152130d0fa0b176ec9b00d15805a9d..1706e0379bfc743409316a7a529a53aba7854855 100644
--- a/chrome/gpu/gpu_channel.h
+++ b/chrome/gpu/gpu_channel.h
@@ -46,7 +46,7 @@ class GpuChannel : public IPC::Channel::Listener,
   }
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
@@ -62,7 +62,7 @@ class GpuChannel : public IPC::Channel::Listener,
 #endif
 
  private:
-  void OnControlMessageReceived(const IPC::Message& msg);
+  bool OnControlMessageReceived(const IPC::Message& msg);
 
   int GenerateRouteID();
 
diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc
index bf3b2d01170f0658e31139697e378ee36fc14e37..592e04f91a97cdaab4c65ea1411969ef948b2950 100644
--- a/chrome/gpu/gpu_command_buffer_stub.cc
+++ b/chrome/gpu/gpu_command_buffer_stub.cc
@@ -169,7 +169,8 @@ GpuCommandBufferStub::~GpuCommandBufferStub() {
 #endif  // defined(OS_WIN)
 }
 
-void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
+bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState);
@@ -187,8 +188,10 @@ void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
 #if defined(OS_MACOSX)
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetWindowSize, OnSetWindowSize);
 #endif  // defined(OS_MACOSX)
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 bool GpuCommandBufferStub::Send(IPC::Message* message) {
diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h
index 66d175997b9ef9075e6bb2ea13b455db9e353930..b90341280ac16044c2a5d0ce0d5d6f5796c7d48c 100644
--- a/chrome/gpu/gpu_command_buffer_stub.h
+++ b/chrome/gpu/gpu_command_buffer_stub.h
@@ -41,7 +41,7 @@ class GpuCommandBufferStub
   virtual ~GpuCommandBufferStub();
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // IPC::Message::Sender implementation:
   virtual bool Send(IPC::Message* msg);
diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc
index b8c532bda02e805db9c5e5fec3d0073280d87697..e95d27f4b40ec7d5b211bbb098f3b7383d3a0128 100644
--- a/chrome/gpu/gpu_thread.cc
+++ b/chrome/gpu/gpu_thread.cc
@@ -52,8 +52,9 @@ void GpuThread::RemoveChannel(int renderer_id) {
   gpu_channels_.erase(renderer_id);
 }
 
-void GpuThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool GpuThread::OnControlMessageReceived(const IPC::Message& msg) {
   bool msg_is_ok = true;
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP_EX(GpuThread, msg, msg_is_ok)
     IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
     IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
@@ -67,7 +68,9 @@ void GpuThread::OnControlMessageReceived(const IPC::Message& msg) {
 #endif
     IPC_MESSAGE_HANDLER(GpuMsg_Crash, OnCrash)
     IPC_MESSAGE_HANDLER(GpuMsg_Hang, OnHang)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
+  return handled;
 }
 
 void GpuThread::OnEstablishChannel(int renderer_id) {
diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h
index 2f2a1f925ae486114c8d82d70bfb4f8ead108213..07302d3fdf3a332cd1b85307af25d185af605bb6 100644
--- a/chrome/gpu/gpu_thread.h
+++ b/chrome/gpu/gpu_thread.h
@@ -33,7 +33,7 @@ class GpuThread : public ChildThread {
 
  private:
   // ChildThread overrides.
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   // Message handlers.
   void OnEstablishChannel(int renderer_id);
diff --git a/chrome/gpu/gpu_video_decoder.cc b/chrome/gpu/gpu_video_decoder.cc
index d16064c7f1e6af58d728606e90dedb1591285194..ee213bf074d93ab66be03cb179cd36d39bafab84 100644
--- a/chrome/gpu/gpu_video_decoder.cc
+++ b/chrome/gpu/gpu_video_decoder.cc
@@ -35,7 +35,8 @@ void GpuVideoDecoder::OnChannelConnected(int32 peer_pid) {
 void GpuVideoDecoder::OnChannelError() {
 }
 
-void GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) {
+bool GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(GpuVideoDecoder, msg)
     IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_Initialize,
                         OnInitialize)
@@ -51,8 +52,10 @@ void GpuVideoDecoder::OnMessageReceived(const IPC::Message& msg) {
                         OnProduceVideoFrame)
     IPC_MESSAGE_HANDLER(GpuVideoDecoderMsg_VideoFrameAllocated,
                         OnVideoFrameAllocated)
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 bool GpuVideoDecoder::CreateInputTransferBuffer(
diff --git a/chrome/gpu/gpu_video_decoder.h b/chrome/gpu/gpu_video_decoder.h
index 79b9bdbbb120b63cb659efdeec70fc4e8b7e5c4f..ae1da3b95eb43d81b631252f070cc5f0e47f619f 100644
--- a/chrome/gpu/gpu_video_decoder.h
+++ b/chrome/gpu/gpu_video_decoder.h
@@ -102,7 +102,7 @@ class GpuVideoDecoder
   // IPC::Channel::Listener implementation.
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // VideoDecodeEngine::EventHandler implementation.
   virtual void OnInitializeComplete(const VideoCodecInfo& info);
diff --git a/chrome/gpu/gpu_video_service.cc b/chrome/gpu/gpu_video_service.cc
index ca9d48255cf131c3a22d839524b9b7d3d949b3f6..fb76e0215d8ed1edff031a80ca5d81be9a7677e8 100644
--- a/chrome/gpu/gpu_video_service.cc
+++ b/chrome/gpu/gpu_video_service.cc
@@ -36,12 +36,13 @@ void GpuVideoService::OnChannelError() {
   LOG(ERROR) << "GpuVideoService::OnChannelError";
 }
 
-void GpuVideoService::OnMessageReceived(const IPC::Message& msg) {
+bool GpuVideoService::OnMessageReceived(const IPC::Message& msg) {
 #if 0
   IPC_BEGIN_MESSAGE_MAP(GpuVideoService, msg)
     IPC_MESSAGE_UNHANDLED_ERROR()
   IPC_END_MESSAGE_MAP()
 #endif
+  return false;
 }
 
 bool GpuVideoService::IntializeGpuVideoService() {
diff --git a/chrome/gpu/gpu_video_service.h b/chrome/gpu/gpu_video_service.h
index b9ad6da531bcdb6cf23492fd2fd00845eeed4bfc..371cf4b3ffe69097e9ad05b01b7af91b59289239 100644
--- a/chrome/gpu/gpu_video_service.h
+++ b/chrome/gpu/gpu_video_service.h
@@ -21,7 +21,7 @@ class GpuVideoService : public IPC::Channel::Listener {
   // IPC::Channel::Listener.
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // TODO(hclam): Remove return value.
   bool CreateVideoDecoder(GpuChannel* channel,
diff --git a/chrome/nacl/broker_thread.cc b/chrome/nacl/broker_thread.cc
index b0cdba5c3f346b66fb11f863530a51ac7738a954..984acb367d8b9e7fdb4de1cf988f0ae7db9ec349 100644
--- a/chrome/nacl/broker_thread.cc
+++ b/chrome/nacl/broker_thread.cc
@@ -28,12 +28,15 @@ NaClBrokerThread* NaClBrokerThread::current() {
   return static_cast<NaClBrokerThread*>(ChildThread::current());
 }
 
-void NaClBrokerThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool NaClBrokerThread::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(NaClBrokerThread, msg)
     IPC_MESSAGE_HANDLER(NaClProcessMsg_LaunchLoaderThroughBroker,
                         OnLaunchLoaderThroughBroker)
     IPC_MESSAGE_HANDLER(NaClProcessMsg_StopBroker, OnStopBroker)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void NaClBrokerThread::OnLaunchLoaderThroughBroker(
diff --git a/chrome/nacl/broker_thread.h b/chrome/nacl/broker_thread.h
index 65906357a9abace77537d3b59e726382f208db58..8b2d7c585f6363772afb1a23f143c28cab153c63 100644
--- a/chrome/nacl/broker_thread.h
+++ b/chrome/nacl/broker_thread.h
@@ -26,7 +26,7 @@ class NaClBrokerThread : public ChildThread {
   virtual void OnChannelConnected(int32 peer_pid);
 
  private:
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
   void OnLaunchLoaderThroughBroker(const std::wstring& loader_channel_id);
   void OnShareBrowserHandle(int browser_handle);
   void OnStopBroker();
diff --git a/chrome/nacl/nacl_thread.cc b/chrome/nacl/nacl_thread.cc
index 15c25b95f460b4a57ec99575c0b224113f310ae8..3ea0f82b4b83c568b96cc3529c5a9962ddf53f17 100644
--- a/chrome/nacl/nacl_thread.cc
+++ b/chrome/nacl/nacl_thread.cc
@@ -76,10 +76,13 @@ NaClThread* NaClThread::current() {
   return static_cast<NaClThread*>(ChildThread::current());
 }
 
-void NaClThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool NaClThread::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(NaClThread, msg)
     IPC_MESSAGE_HANDLER(NaClProcessMsg_Start, OnStartSelLdr)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void NaClThread::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles) {
diff --git a/chrome/nacl/nacl_thread.h b/chrome/nacl/nacl_thread.h
index f87fc969c3a7255cf65b7c80e4bcaaaa5aae67e7..b330794949c3259b6645f8b1da93d2d64f082bdd 100644
--- a/chrome/nacl/nacl_thread.h
+++ b/chrome/nacl/nacl_thread.h
@@ -20,7 +20,7 @@ class NaClThread : public ChildThread {
   static NaClThread* current();
 
  private:
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
   void OnStartSelLdr(std::vector<nacl::FileDescriptor> handles);
 
   int debug_enabled_;
diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc
index 58184149af52448b444bc84e266085bfc407fbcd..de9bbdb16e28382b8ae2296a40cd40fe50667fff 100644
--- a/chrome/plugin/command_buffer_stub.cc
+++ b/chrome/plugin/command_buffer_stub.cc
@@ -27,7 +27,8 @@ CommandBufferStub::~CommandBufferStub() {
   channel_->RemoveRoute(route_id_);
 }
 
-void CommandBufferStub::OnMessageReceived(const IPC::Message& message) {
+bool CommandBufferStub::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(CommandBufferStub, message)
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState);
@@ -43,8 +44,10 @@ void CommandBufferStub::OnMessageReceived(const IPC::Message& message) {
 #if defined(OS_MACOSX)
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetWindowSize, OnSetWindowSize);
 #endif
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void CommandBufferStub::OnChannelError() {
diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h
index 7519659139f04625059d8ab69ce7365308311516..e9f65c66e88aae213610350f9163c93c5f6e15ce 100644
--- a/chrome/plugin/command_buffer_stub.h
+++ b/chrome/plugin/command_buffer_stub.h
@@ -31,7 +31,7 @@ class CommandBufferStub : public IPC::Channel::Listener,
   virtual ~CommandBufferStub();
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelError();
 
   // IPC::Message::Sender implementation:
diff --git a/chrome/plugin/npobject_proxy.cc b/chrome/plugin/npobject_proxy.cc
index 0b7ff45911cc3042c73af00e3d380a922838a8eb..8a429fba0b2074c3c74dd575def8af8cb9d70545 100644
--- a/chrome/plugin/npobject_proxy.cc
+++ b/chrome/plugin/npobject_proxy.cc
@@ -104,8 +104,9 @@ void NPObjectProxy::NPDeallocate(NPObject* npObj) {
   delete obj;
 }
 
-void NPObjectProxy::OnMessageReceived(const IPC::Message& msg) {
+bool NPObjectProxy::OnMessageReceived(const IPC::Message& msg) {
   NOTREACHED();
+  return false;
 }
 
 void NPObjectProxy::OnChannelError() {
diff --git a/chrome/plugin/npobject_proxy.h b/chrome/plugin/npobject_proxy.h
index 6b6e7fff38bf107951be72f63a491e34898f4b2a..4b6b5954d3600055f024facf3a4133924772dd9e 100644
--- a/chrome/plugin/npobject_proxy.h
+++ b/chrome/plugin/npobject_proxy.h
@@ -102,7 +102,7 @@ class NPObjectProxy : public IPC::Channel::Listener,
                 const GURL& page_url);
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
   static NPObject* NPAllocate(NPP, NPClass*);
diff --git a/chrome/plugin/npobject_stub.cc b/chrome/plugin/npobject_stub.cc
index e0a8436d790a3076f29bb94f924bdaaf8f577a32..7fd18ddc483c3cb312ff4863135d12ca9313e347 100644
--- a/chrome/plugin/npobject_stub.cc
+++ b/chrome/plugin/npobject_stub.cc
@@ -62,7 +62,7 @@ IPC::Channel::Listener* NPObjectStub::GetChannelListener() {
   return static_cast<IPC::Channel::Listener*>(this);
 }
 
-void NPObjectStub::OnMessageReceived(const IPC::Message& msg) {
+bool NPObjectStub::OnMessageReceived(const IPC::Message& msg) {
   child_process_logging::SetActiveURL(page_url_);
 
   if (!npobject_) {
@@ -74,9 +74,10 @@ void NPObjectStub::OnMessageReceived(const IPC::Message& msg) {
       Send(reply);
     }
 
-    return;
+    return true;
   }
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(NPObjectStub, msg)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Release, OnRelease);
     IPC_MESSAGE_HANDLER(NPObjectMsg_HasMethod, OnHasMethod);
@@ -89,8 +90,10 @@ void NPObjectStub::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(NPObjectMsg_Enumeration, OnEnumeration);
     IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Construct, OnConstruct);
     IPC_MESSAGE_HANDLER_DELAY_REPLY(NPObjectMsg_Evaluate, OnEvaluate);
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void NPObjectStub::OnChannelError() {
diff --git a/chrome/plugin/npobject_stub.h b/chrome/plugin/npobject_stub.h
index 248d001f280e4cb742f02798b68460f5ee4dd04c..d43fbad4af12699b2a4107c8bea56900f3917bbb 100644
--- a/chrome/plugin/npobject_stub.h
+++ b/chrome/plugin/npobject_stub.h
@@ -53,7 +53,7 @@ class NPObjectStub : public IPC::Channel::Listener,
 
  private:
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelError();
 
   // message handlers
diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc
index bc5e61ee425ee03c1e2da99f823639378d38c181..fc789353e86d972308b7249067924d385163ec35 100644
--- a/chrome/plugin/plugin_channel.cc
+++ b/chrome/plugin/plugin_channel.cc
@@ -190,23 +190,26 @@ bool PluginChannel::Send(IPC::Message* msg) {
   return result;
 }
 
-void PluginChannel::OnMessageReceived(const IPC::Message& msg) {
+bool PluginChannel::OnMessageReceived(const IPC::Message& msg) {
   if (log_messages_) {
     VLOG(1) << "received message @" << &msg << " on channel @" << this
             << " with type " << msg.type();
   }
-  PluginChannelBase::OnMessageReceived(msg);
+  return PluginChannelBase::OnMessageReceived(msg);
 }
 
-void PluginChannel::OnControlMessageReceived(const IPC::Message& msg) {
+bool PluginChannel::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PluginChannel, msg)
     IPC_MESSAGE_HANDLER(PluginMsg_CreateInstance, OnCreateInstance)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_DestroyInstance,
                                     OnDestroyInstance)
     IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID)
     IPC_MESSAGE_HANDLER(PluginMsg_ClearSiteData, OnClearSiteData)
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void PluginChannel::OnCreateInstance(const std::string& mime_type,
diff --git a/chrome/plugin/plugin_channel.h b/chrome/plugin/plugin_channel.h
index 519e03c59cd0b5262e995abd00bfe235346227ec..102d4d65ec2578002d0cfb3702419610f322a927 100644
--- a/chrome/plugin/plugin_channel.h
+++ b/chrome/plugin/plugin_channel.h
@@ -33,7 +33,7 @@ class PluginChannel : public PluginChannelBase {
   virtual ~PluginChannel();
 
   virtual bool Send(IPC::Message* msg);
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   base::ProcessHandle renderer_handle() const { return renderer_handle_; }
   int renderer_id() { return renderer_id_; }
@@ -69,7 +69,7 @@ class PluginChannel : public PluginChannelBase {
   // Called on the plugin thread
   PluginChannel();
 
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   static PluginChannelBase* ClassFactory() { return new PluginChannel(); }
 
diff --git a/chrome/plugin/plugin_channel_base.cc b/chrome/plugin/plugin_channel_base.cc
index 37bc1c4c4d874aa15107f1da293fac293bcc2e31..e251e9e57a3fe731ee2c826c2ff7d0774241d992 100644
--- a/chrome/plugin/plugin_channel_base.cc
+++ b/chrome/plugin/plugin_channel_base.cc
@@ -140,19 +140,20 @@ int PluginChannelBase::Count() {
   return static_cast<int>(g_plugin_channels_.size());
 }
 
-void PluginChannelBase::OnMessageReceived(const IPC::Message& message) {
+bool PluginChannelBase::OnMessageReceived(const IPC::Message& message) {
   // This call might cause us to be deleted, so keep an extra reference to
   // ourself so that we can send the reply and decrement back in_dispatch_.
   lazy_plugin_channel_stack_.Pointer()->push(
       scoped_refptr<PluginChannelBase>(this));
 
+  bool handled;
   if (message.should_unblock())
     in_unblock_dispatch_++;
   if (message.routing_id() == MSG_ROUTING_CONTROL) {
-    OnControlMessageReceived(message);
+    handled = OnControlMessageReceived(message);
   } else {
-    bool routed = router_.RouteMessage(message);
-    if (!routed && message.is_sync()) {
+    handled = router_.RouteMessage(message);
+    if (!handled && message.is_sync()) {
       // The listener has gone away, so we must respond or else the caller will
       // hang waiting for a reply.
       IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
@@ -164,6 +165,7 @@ void PluginChannelBase::OnMessageReceived(const IPC::Message& message) {
     in_unblock_dispatch_--;
 
   lazy_plugin_channel_stack_.Pointer()->pop();
+  return handled;
 }
 
 void PluginChannelBase::OnChannelConnected(int32 peer_pid) {
@@ -228,9 +230,10 @@ void PluginChannelBase::RemoveRoute(int route_id) {
   }
 }
 
-void PluginChannelBase::OnControlMessageReceived(const IPC::Message& msg) {
+bool PluginChannelBase::OnControlMessageReceived(const IPC::Message& msg) {
   NOTREACHED() <<
       "should override in subclass if you care about control messages";
+  return false;
 }
 
 void PluginChannelBase::OnChannelError() {
diff --git a/chrome/plugin/plugin_channel_base.h b/chrome/plugin/plugin_channel_base.h
index 22103e8b6f7c317a20dbc79d339d6974a9c0d716..d1a1a1cc6cdb401a069bed5be2765c143fc43e54 100644
--- a/chrome/plugin/plugin_channel_base.h
+++ b/chrome/plugin/plugin_channel_base.h
@@ -89,10 +89,10 @@ class PluginChannelBase : public IPC::Channel::Listener,
   virtual void CleanUp() { }
 
   // Implemented by derived classes to handle control messages
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index 8edcbbdb4e2e4ce3419eaeba53670256c149e6f5..d5757e12e1496f5f6b52e54565ab87046eaa625a 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -128,13 +128,16 @@ PluginThread* PluginThread::current() {
   return lazy_tls.Pointer()->Get();
 }
 
-void PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PluginThread, msg)
     IPC_MESSAGE_HANDLER(PluginProcessMsg_CreateChannel, OnCreateChannel)
     IPC_MESSAGE_HANDLER(PluginProcessMsg_PluginMessage, OnPluginMessage)
     IPC_MESSAGE_HANDLER(PluginProcessMsg_NotifyRenderersOfPendingShutdown,
                         OnNotifyRenderersOfPendingShutdown)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PluginThread::OnCreateChannel(int renderer_id,
diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h
index 4d24e3c14283678818ef9d82ab7de1f49d483a9a..f5ef2679b294961342a975f5674161b878d420e3 100644
--- a/chrome/plugin/plugin_thread.h
+++ b/chrome/plugin/plugin_thread.h
@@ -31,7 +31,7 @@ class PluginThread : public ChildThread {
   FilePath plugin_path() { return plugin_path_; }
 
  private:
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   // Callback for when a channel has been created.
   void OnCreateChannel(int renderer_id, bool off_the_record);
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index 0540adf4ad3c05ec8dc6e82e643ed800c5be16da..41b0256840898e390d5aaf20a051d9f9808e5762 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -88,7 +88,7 @@ WebPluginDelegateStub::~WebPluginDelegateStub() {
   }
 }
 
-void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
+bool WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
   child_process_logging::SetActiveURL(page_url_);
 
   // A plugin can execute a script to delete itself in any of its NPP methods.
@@ -98,6 +98,7 @@ void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
   if (!in_destructor_)
     AddRef();
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateStub, msg)
     IPC_MESSAGE_HANDLER(PluginMsg_Init, OnInit)
     IPC_MESSAGE_HANDLER(PluginMsg_WillSendRequest, OnWillSendRequest)
@@ -146,11 +147,14 @@ void WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(PluginMsg_SetFakeAcceleratedSurfaceWindowHandle,
                         OnSetFakeAcceleratedSurfaceWindowHandle)
 #endif
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
   if (!in_destructor_)
     Release();
+
+  DCHECK(handled);
+  return handled;
 }
 
 bool WebPluginDelegateStub::Send(IPC::Message* msg) {
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index c310467a637e07eafd197437bd8235310230c1c5..0a95587107e20238b44e8c83ce49e8751d519ef2 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -45,7 +45,7 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
                         PluginChannel* channel);
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // IPC::Message::Sender implementation:
   virtual bool Send(IPC::Message* msg);
diff --git a/chrome/ppapi_plugin/ppapi_thread.cc b/chrome/ppapi_plugin/ppapi_thread.cc
index be6075d08804a2d92f38b382d2f5fc7ff73e9bc2..0fc5acec54e274e394e18fb9a07526c235da1431 100644
--- a/chrome/ppapi_plugin/ppapi_thread.cc
+++ b/chrome/ppapi_plugin/ppapi_thread.cc
@@ -35,7 +35,7 @@ PpapiThread::~PpapiThread() {
 // Note that this function is called only for messages from the channel to the
 // browser process. Messages from the renderer process are sent via a different
 // channel that ends up at Dispatcher::OnMessageReceived.
-void PpapiThread::OnMessageReceived(const IPC::Message& msg) {
+bool PpapiThread::OnMessageReceived(const IPC::Message& msg) {
   IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
     IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin)
 
@@ -45,6 +45,7 @@ void PpapiThread::OnMessageReceived(const IPC::Message& msg) {
         dispatcher_->OnMessageReceived(msg)
     )*/
   IPC_END_MESSAGE_MAP()
+  return true;
 }
 
 void PpapiThread::OnMsgLoadPlugin(base::ProcessHandle host_process_handle,
diff --git a/chrome/ppapi_plugin/ppapi_thread.h b/chrome/ppapi_plugin/ppapi_thread.h
index 215d1bd01f7a8b4584330241a35477b7d1cebf65..08e62fca74c45f72fcd0f5430c115b911be13e33 100644
--- a/chrome/ppapi_plugin/ppapi_thread.h
+++ b/chrome/ppapi_plugin/ppapi_thread.h
@@ -32,7 +32,7 @@ class PpapiThread : public ChildThread {
 
  private:
   // ChildThread overrides.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // Message handlers.
   void OnMsgLoadPlugin(base::ProcessHandle renderer_handle,
diff --git a/chrome/profile_import/profile_import_thread.cc b/chrome/profile_import/profile_import_thread.cc
index 23685730b6ea6a9f12a84f63b54627d2d85994b3..f7a665b785273b3e1c0463823e87514a54d74723 100644
--- a/chrome/profile_import/profile_import_thread.cc
+++ b/chrome/profile_import/profile_import_thread.cc
@@ -34,7 +34,8 @@ ProfileImportThread::ProfileImportThread()
 
 ProfileImportThread::~ProfileImportThread() {}
 
-void ProfileImportThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool ProfileImportThread::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ProfileImportThread, msg)
     IPC_MESSAGE_HANDLER(ProfileImportProcessMsg_StartImport,
                         OnImportStart)
@@ -42,7 +43,9 @@ void ProfileImportThread::OnControlMessageReceived(const IPC::Message& msg) {
                         OnImportCancel)
     IPC_MESSAGE_HANDLER(ProfileImportProcessMsg_ReportImportItemFinished,
                         OnImportItemFinished)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void ProfileImportThread::OnImportStart(
diff --git a/chrome/profile_import/profile_import_thread.h b/chrome/profile_import/profile_import_thread.h
index 079fa4ccfc8790ee58f041e63fe59fb702d1618d..0c86885e64379eec0ecc3d208b591b16ca40c40d 100644
--- a/chrome/profile_import/profile_import_thread.h
+++ b/chrome/profile_import/profile_import_thread.h
@@ -56,7 +56,7 @@ class ProfileImportThread : public ChildThread {
 
  private:
   // IPC messages
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   // Creates the importer and launches it in a new thread. Import is run on
   // a separate thread so that this thread can receive messages from the
diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc
index 0cc1e6a270023e6f2aaecf4b3a9cd4bd89d95cb8..21eee90e07cc66b75bb8263b19dfe0414eaaa4f2 100644
--- a/chrome/renderer/command_buffer_proxy.cc
+++ b/chrome/renderer/command_buffer_proxy.cc
@@ -34,14 +34,17 @@ CommandBufferProxy::~CommandBufferProxy() {
   }
 }
 
-void CommandBufferProxy::OnMessageReceived(const IPC::Message& message) {
+bool CommandBufferProxy::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(CommandBufferProxy, message)
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UpdateState, OnUpdateState);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SwapBuffers, OnSwapBuffers);
     IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_NotifyRepaint,
                         OnNotifyRepaint);
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void CommandBufferProxy::OnChannelError() {
diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h
index 245c0580de21b4fd3437a47169151c4d58975c36..6f3688f86b4b929dc3bda430c739666ee82a49d5 100644
--- a/chrome/renderer/command_buffer_proxy.h
+++ b/chrome/renderer/command_buffer_proxy.h
@@ -38,7 +38,7 @@ class CommandBufferProxy : public gpu::CommandBuffer,
   virtual ~CommandBufferProxy();
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelError();
 
   int route_id() const { return route_id_; }
diff --git a/chrome/renderer/device_orientation_dispatcher.h b/chrome/renderer/device_orientation_dispatcher.h
index e2abf375d62a8ab30ae183a08a930db402526d95..88c1ef50127864434cac60658b6b7d03a30bc0cd 100644
--- a/chrome/renderer/device_orientation_dispatcher.h
+++ b/chrome/renderer/device_orientation_dispatcher.h
@@ -8,18 +8,20 @@
 #include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientationClient.h"
 
 #include "base/scoped_ptr.h"
+#include "ipc/ipc_channel.h"
 
 class RenderView;
-namespace IPC { class Message; }
 namespace WebKit { class WebDeviceOrientation; }
 
 struct ViewMsg_DeviceOrientationUpdated_Params;
 
-class DeviceOrientationDispatcher : public WebKit::WebDeviceOrientationClient {
+class DeviceOrientationDispatcher : public WebKit::WebDeviceOrientationClient,
+                                    public IPC::Channel::Listener {
  public:
   explicit DeviceOrientationDispatcher(RenderView* render_view);
   virtual ~DeviceOrientationDispatcher();
 
+  // IPC::Channel::Implementation.
   bool OnMessageReceived(const IPC::Message& msg);
 
   // From WebKit::WebDeviceOrientationClient.
diff --git a/chrome/renderer/devtools_agent.h b/chrome/renderer/devtools_agent.h
index ebb06dd2ceb36f8996762132c98f8ff856cc9ea5..14a72473dc58b326a90fa59a2b1bffa1caa8abc0 100644
--- a/chrome/renderer/devtools_agent.h
+++ b/chrome/renderer/devtools_agent.h
@@ -11,12 +11,9 @@
 
 #include "base/basictypes.h"
 #include "chrome/common/devtools_messages.h"
+#include "ipc/ipc_channel.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebDevToolsAgentClient.h"
 
-namespace IPC {
-class Message;
-}
-
 namespace WebKit {
 class WebDevToolsAgent;
 }
@@ -28,14 +25,15 @@ struct DevToolsMessageData;
 // agents with the communication capabilities. All messages from/to Glue's
 // agents infrastructure are flowing through this comminucation agent.
 // There is a corresponding DevToolsClient object on the client side.
-class DevToolsAgent : public WebKit::WebDevToolsAgentClient {
+class DevToolsAgent : public WebKit::WebDevToolsAgentClient,
+                      public IPC::Channel::Listener {
  public:
   DevToolsAgent(int routing_id, RenderView* view);
   virtual ~DevToolsAgent();
 
   void OnNavigate();
 
-  // IPC message interceptor. Called on the Render thread.
+  // IPC::Channel::Listener implementation.
   virtual bool OnMessageReceived(const IPC::Message& message);
 
   // WebDevToolsAgentClient implementation
diff --git a/chrome/renderer/devtools_client.h b/chrome/renderer/devtools_client.h
index 577e18924b3864270a9576edc5380fd3743733bc..463dc3524b4851ad37e1dee9d3db6da8b4511a4f 100644
--- a/chrome/renderer/devtools_client.h
+++ b/chrome/renderer/devtools_client.h
@@ -10,11 +10,9 @@
 
 #include "base/basictypes.h"
 #include "base/scoped_ptr.h"
+#include "ipc/ipc_channel.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebDevToolsFrontendClient.h"
 
-namespace IPC {
-class Message;
-}
 class MessageLoop;
 class RenderView;
 
@@ -31,13 +29,13 @@ struct DevToolsMessageData;
 // corresponding DevToolsAgent object.
 // TODO(yurys): now the client is almost empty later it will delegate calls to
 // code in glue
-class DevToolsClient : public WebKit::WebDevToolsFrontendClient {
+class DevToolsClient : public WebKit::WebDevToolsFrontendClient,
+                       public IPC::Channel::Listener {
  public:
   explicit DevToolsClient(RenderView* view);
   virtual ~DevToolsClient();
 
-  // Called to possibly handle the incoming IPC message. Returns true if
-  // handled. Called in render thread.
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& message);
 
   // WebDevToolsFrontendClient implementation
diff --git a/chrome/renderer/geolocation_dispatcher_old.h b/chrome/renderer/geolocation_dispatcher_old.h
index 51567ef5c377d9d2f565ce3907e46566f1c7199e..ab93c14d2b2688083811b87ab14db9e34db8e025 100644
--- a/chrome/renderer/geolocation_dispatcher_old.h
+++ b/chrome/renderer/geolocation_dispatcher_old.h
@@ -12,7 +12,7 @@
 
 #include "base/basictypes.h"
 #include "base/id_map.h"
-#include "ipc/ipc_message.h"
+#include "ipc/ipc_channel.h"
 #include "googleurl/src/gurl.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebGeolocationService.h"
 
@@ -25,13 +25,13 @@ struct Geoposition;
 // It's the complement of GeolocationDispatcherHostOld (owned by
 // RenderViewHost).
 
-class GeolocationDispatcherOld : public WebKit::WebGeolocationService {
+class GeolocationDispatcherOld : public WebKit::WebGeolocationService,
+                                 public IPC::Channel::Listener {
  public:
   explicit GeolocationDispatcherOld(RenderView* render_view);
   virtual ~GeolocationDispatcherOld();
 
-  // Called to possibly handle the incoming IPC message. Returns true if
-  // handled. Called in render thread.
+  // IPC::Channel::Listener implementation
   bool OnMessageReceived(const IPC::Message& msg);
 
   // WebKit::WebGeolocationService.
diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc
index 80baea93b89861e25fb456d6a7a963081bdc6243..ecf7bfc5e1c4e19e23721cd7ff4dea4b4671ae26 100644
--- a/chrome/renderer/gpu_channel_host.cc
+++ b/chrome/renderer/gpu_channel_host.cc
@@ -37,14 +37,14 @@ const GPUInfo& GpuChannelHost::gpu_info() const {
   return gpu_info_;
 }
 
-void GpuChannelHost::OnMessageReceived(const IPC::Message& message) {
+bool GpuChannelHost::OnMessageReceived(const IPC::Message& message) {
   DCHECK(message.routing_id() != MSG_ROUTING_CONTROL);
 
   // The object to which the message is addressed might have been destroyed.
   // This is expected, for example an asynchronous SwapBuffers notification
   // to a command buffer proxy that has since been destroyed. This function
   // fails silently in that case.
-  router_.RouteMessage(message);
+  return router_.RouteMessage(message);
 }
 
 void GpuChannelHost::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome/renderer/gpu_channel_host.h b/chrome/renderer/gpu_channel_host.h
index 8d9c68423cfd4f69d4df44aa5be72b2116ff4291..42eebba287a45656a692c553725ea3ab27cdbcbf 100644
--- a/chrome/renderer/gpu_channel_host.h
+++ b/chrome/renderer/gpu_channel_host.h
@@ -53,7 +53,7 @@ class GpuChannelHost : public IPC::Channel::Listener,
   const GPUInfo& gpu_info() const;
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/renderer/gpu_video_decoder_host.cc b/chrome/renderer/gpu_video_decoder_host.cc
index 44599f3e4461390107d1bc62f7fbd341e127d69c..9d9ba042c4c8e99b79dea706bd5e5bc40985d02d 100644
--- a/chrome/renderer/gpu_video_decoder_host.cc
+++ b/chrome/renderer/gpu_video_decoder_host.cc
@@ -32,7 +32,8 @@ void GpuVideoDecoderHost::OnChannelError() {
   ipc_sender_ = NULL;
 }
 
-void GpuVideoDecoderHost::OnMessageReceived(const IPC::Message& msg) {
+bool GpuVideoDecoderHost::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(GpuVideoDecoderHost, msg)
     IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_CreateVideoDecoderDone,
                         OnCreateVideoDecoderDone)
@@ -54,8 +55,10 @@ void GpuVideoDecoderHost::OnMessageReceived(const IPC::Message& msg) {
                         OnAllocateVideoFrames)
     IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_ReleaseAllVideoFrames,
                         OnReleaseAllVideoFrames)
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void GpuVideoDecoderHost::Initialize(
diff --git a/chrome/renderer/gpu_video_decoder_host.h b/chrome/renderer/gpu_video_decoder_host.h
index c32a9f032731c26f49d0609986997a9eb72734c3..a7a3a71ef0a23a53dc688faf924ea87b3c9d630d 100644
--- a/chrome/renderer/gpu_video_decoder_host.h
+++ b/chrome/renderer/gpu_video_decoder_host.h
@@ -50,7 +50,7 @@ class GpuVideoDecoderHost : public media::VideoDecodeEngine,
   // IPC::Channel::Listener.
   virtual void OnChannelConnected(int32 peer_pid) {}
   virtual void OnChannelError();
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // media::VideoDecodeEngine implementation.
   virtual void Initialize(MessageLoop* message_loop,
diff --git a/chrome/renderer/indexed_db_dispatcher.h b/chrome/renderer/indexed_db_dispatcher.h
index 121055196408ebafc916ecb3140583a2ed2c41f0..8012015815a65035152d755a1c01515addec23b9 100644
--- a/chrome/renderer/indexed_db_dispatcher.h
+++ b/chrome/renderer/indexed_db_dispatcher.h
@@ -8,7 +8,7 @@
 
 #include "base/id_map.h"
 #include "base/nullable_string16.h"
-#include "ipc/ipc_message.h"
+#include "ipc/ipc_channel.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebExceptionCode.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebIDBCallbacks.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebIDBDatabase.h"
@@ -24,13 +24,12 @@ class WebIDBTransaction;
 }
 
 // Handle the indexed db related communication for this entire renderer.
-class IndexedDBDispatcher {
+class IndexedDBDispatcher : public IPC::Channel::Listener {
  public:
   IndexedDBDispatcher();
   ~IndexedDBDispatcher();
 
-  // Called to possibly handle the incoming IPC message. Returns true if
-  // handled.
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& msg);
 
   void RequestIDBFactoryOpen(
diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc
index c188f34a28967aae40017a0979e76b8ffc7050bb..1d98d6ed66746d9fe228aea8408c31f8a21815be 100644
--- a/chrome/renderer/mock_render_thread.cc
+++ b/chrome/renderer/mock_render_thread.cc
@@ -81,7 +81,7 @@ void MockRenderThread::SendCloseMessage() {
   widget_->OnMessageReceived(msg);
 }
 
-void MockRenderThread::OnMessageReceived(const IPC::Message& msg) {
+bool MockRenderThread::OnMessageReceived(const IPC::Message& msg) {
   // Save the message in the sink.
   sink_.OnMessageReceived(msg);
 
@@ -116,6 +116,7 @@ void MockRenderThread::OnMessageReceived(const IPC::Message& msg) {
 #endif
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
+  return handled;
 }
 
 // The Widget expects to be returned valid route_id.
diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h
index a1b58a59e8228baccbf0c8ad98b289b5f551f61e..2a6dc60de898b0a4218aa7495ff6bee133e7e23a 100644
--- a/chrome/renderer/mock_render_thread.h
+++ b/chrome/renderer/mock_render_thread.h
@@ -82,7 +82,7 @@ class MockRenderThread : public RenderThreadBase {
 
  private:
   // This function operates as a regular IPC listener.
-  void OnMessageReceived(const IPC::Message& msg);
+  bool OnMessageReceived(const IPC::Message& msg);
 
   // The Widget expects to be returned valid route_id.
   void OnMsgCreateWidget(int opener_id,
diff --git a/chrome/renderer/notification_provider.h b/chrome/renderer/notification_provider.h
index ccd6cf35ddf9bfa1273babf2b36076e50d70fd50..1ba84b2c3e047a972e50818f105d8538c1867431 100644
--- a/chrome/renderer/notification_provider.h
+++ b/chrome/renderer/notification_provider.h
@@ -18,7 +18,8 @@ class WebNotificationPermissionCallback;
 
 // NotificationProvider class is owned by the RenderView.  Only
 // to be used on the UI thread.
-class NotificationProvider : public WebKit::WebNotificationPresenter {
+class NotificationProvider : public WebKit::WebNotificationPresenter,
+                             public IPC::Channel::Listener {
  public:
   explicit NotificationProvider(RenderView* view);
   virtual ~NotificationProvider();
@@ -32,7 +33,7 @@ class NotificationProvider : public WebKit::WebNotificationPresenter {
   virtual void requestPermission(const WebKit::WebSecurityOrigin& origin,
       WebKit::WebNotificationPermissionCallback* callback);
 
-  // IPC message handler called from RenderView.
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& message);
 
   // Called when the RenderView navigates.
diff --git a/chrome/renderer/plugin_channel_host.cc b/chrome/renderer/plugin_channel_host.cc
index b6a93c06927b03d3fc15f284dfe0cebdc0530aed..34d146179451eb6f21ed96699aad29d72713b517 100644
--- a/chrome/renderer/plugin_channel_host.cc
+++ b/chrome/renderer/plugin_channel_host.cc
@@ -114,12 +114,15 @@ void PluginChannelHost::RemoveRoute(int route_id) {
   PluginChannelBase::RemoveRoute(route_id);
 }
 
-void PluginChannelHost::OnControlMessageReceived(const IPC::Message& message) {
+bool PluginChannelHost::OnControlMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PluginChannelHost, message)
     IPC_MESSAGE_HANDLER(PluginHostMsg_SetException, OnSetException)
     IPC_MESSAGE_HANDLER(PluginHostMsg_PluginShuttingDown, OnPluginShuttingDown)
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void PluginChannelHost::OnSetException(const std::string& message) {
diff --git a/chrome/renderer/plugin_channel_host.h b/chrome/renderer/plugin_channel_host.h
index 241833f57d34e0435d9553afed89c50da74daa25..5f6d556bf7cfc233c3e10f30c6473c4eb5aeeacc 100644
--- a/chrome/renderer/plugin_channel_host.h
+++ b/chrome/renderer/plugin_channel_host.h
@@ -48,7 +48,7 @@ class PluginChannelHost : public PluginChannelBase {
 
   static PluginChannelBase* ClassFactory() { return new PluginChannelHost(); }
 
-  virtual void OnControlMessageReceived(const IPC::Message& message);
+  virtual bool OnControlMessageReceived(const IPC::Message& message);
   void OnSetException(const std::string& message);
   void OnPluginShuttingDown(const IPC::Message& message);
 
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 5fc265e1ced0e93e4aea9822a9fe2c372929ccbd..f1f10089454cc718f077536c910f8df71bd6f2bf 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -593,13 +593,14 @@ void RenderThread::OnDOMStorageEvent(
       params.storage_type == DOM_STORAGE_LOCAL);
 }
 
-void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
   // Some messages are handled by delegates.
   if (appcache_dispatcher_->OnMessageReceived(msg))
-    return;
+    return true;
   if (indexed_db_dispatcher_->OnMessageReceived(msg))
-    return;
+    return true;
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
     IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
     IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_Add, OnAddVisitedLinks)
@@ -660,7 +661,9 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(ViewMsg_SetPhishingModel, OnSetPhishingModel)
     IPC_MESSAGE_HANDLER(ViewMsg_SpeechInput_SetFeatureEnabled,
                         OnSetSpeechInputEnabled)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void RenderThread::OnSetSpeechInputEnabled(bool enabled) {
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 6946a47d976e9fc427f3782c94f8312c93cf5cb8..6817cfb62b6e0f51f8134db100f55a0db191fae5 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -254,7 +254,7 @@ class RenderThread : public RenderThreadBase,
                             int extension_group);
 
  private:
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
 
   void Init();
 
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 7a84c116ad7a158ca600e1993dd4868287d92a22..1a9aef5582cddc1235f534df8b46e9407f66fcd3 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -944,31 +944,32 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd,
   render_thread_->AddFilter(audio_message_filter_);
 }
 
-void RenderView::OnMessageReceived(const IPC::Message& message) {
+bool RenderView::OnMessageReceived(const IPC::Message& message) {
   WebFrame* main_frame = webview() ? webview()->mainFrame() : NULL;
   if (main_frame)
     child_process_logging::SetActiveURL(main_frame->url());
 
   // If this is developer tools renderer intercept tools messages first.
   if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
-    return;
+    return true;
   if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
-    return;
+    return true;
   if (notification_provider_->OnMessageReceived(message))
-    return;
+    return true;
   if (geolocation_dispatcher_.get() &&
       geolocation_dispatcher_->OnMessageReceived(message)) {
-    return;
+    return true;
   }
   if (speech_input_dispatcher_.get() &&
       speech_input_dispatcher_->OnMessageReceived(message)) {
-    return;
+    return true;
   }
   if (device_orientation_dispatcher_.get() &&
       device_orientation_dispatcher_->OnMessageReceived(message)) {
-    return;
+    return true;
   }
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(RenderView, message)
     IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, OnCaptureThumbnail)
     IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot)
@@ -1102,8 +1103,9 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
     IPC_MESSAGE_HANDLER(ViewMsg_PrintPreview, OnPrintPreview)
 
     // Have the super handle all other messages.
-    IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message))
+    IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message))
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void RenderView::OnCaptureThumbnail() {
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 1f97fa6887865adb0931c87004958b3d5a366597..862ed6c7f17cc86e72384b1747213e4c01b484d8 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -388,7 +388,7 @@ class RenderView : public RenderWidget,
 
   // IPC::Channel::Listener implementation -------------------------------------
 
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // WebKit::WebWidgetClient implementation ------------------------------------
 
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index 9cf323c3a29438d25f45c583a846924a27284d20..2f145765acd5eb0195223f4e01e4cd675e1c6dbb 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -153,25 +153,29 @@ void RenderWidget::CompleteInit(gfx::NativeViewId parent_hwnd) {
   Send(new ViewHostMsg_RenderViewReady(routing_id_));
 }
 
-IPC_DEFINE_MESSAGE_MAP(RenderWidget)
-  IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
-  IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)
-  IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
-  IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
-  IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored)
-  IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck)
-  IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent)
-  IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost)
-  IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus)
-  IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive)
-  IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
-  IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition)
-  IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize)
-  IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint)
-  IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
-  IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
-  IPC_MESSAGE_UNHANDLED_ERROR()
-IPC_END_MESSAGE_MAP()
+bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
+    IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
+    IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)
+    IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
+    IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
+    IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored)
+    IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck)
+    IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent)
+    IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive)
+    IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
+    IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition)
+    IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize)
+    IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint)
+    IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
+    IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
 
 bool RenderWidget::Send(IPC::Message* message) {
   // Don't send any messages after the browser has told us to close.
diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h
index bf542bf44eca60e342e16e97ba248a5aa2edc681..f847ce2ee220c17cd4d207264818fb84e0031148 100644
--- a/chrome/renderer/render_widget.h
+++ b/chrome/renderer/render_widget.h
@@ -92,7 +92,7 @@ class RenderWidget : public IPC::Channel::Listener,
   bool has_focus() const { return has_focus_; }
 
   // IPC::Channel::Listener
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // IPC::Message::Sender
   virtual bool Send(IPC::Message* msg);
diff --git a/chrome/renderer/renderer_main_unittest.cc b/chrome/renderer/renderer_main_unittest.cc
index 464419bcd0d799f3c73dd6bed9ba59fed44022c1..653e02ff7d53dfa807143d1526a8d271f9a8864f 100644
--- a/chrome/renderer/renderer_main_unittest.cc
+++ b/chrome/renderer/renderer_main_unittest.cc
@@ -89,9 +89,10 @@ class SuicidalListener : public IPC::Channel::Listener {
     MessageLoop::current()->Quit();
   }
 
-  void OnMessageReceived(const IPC::Message& message) {
+  bool OnMessageReceived(const IPC::Message& message) {
     // We shouldn't receive any messages
-    ASSERT_TRUE(false);
+    NOTREACHED();
+    return false;
   }
 };
 
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
index f84b0bd0821da86a080112876b01692508fc78ce..edb53946cdb1b4cc0219406e03d5e8e12ec43012 100644
--- a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
+++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
@@ -59,13 +59,15 @@ class MockScorer : public Scorer {
 
 class PhishingClassifierDelegateTest : public RenderViewFakeResourcesTest {
  protected:
-  void OnMessageReceived(const IPC::Message& message) {
+  bool OnMessageReceived(const IPC::Message& message) {
+    bool handled = true;
     IPC_BEGIN_MESSAGE_MAP(PhishingClassifierDelegateTest, message)
       IPC_MESSAGE_HANDLER(ViewHostMsg_DetectedPhishingSite,
                           OnDetectedPhishingSite)
       IPC_MESSAGE_UNHANDLED(
-          RenderViewFakeResourcesTest::OnMessageReceived(message))
+          handled = RenderViewFakeResourcesTest::OnMessageReceived(message))
     IPC_END_MESSAGE_MAP()
+    return handled;
   }
 
   void OnDetectedPhishingSite(GURL phishing_url,
diff --git a/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc b/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc
index e7453730759865d16bdd62e663fdcd938f11112b..bc52ef2b6c4b9dfb743777ac6821a6a3aba11370 100644
--- a/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc
+++ b/chrome/renderer/safe_browsing/render_view_fake_resources_test.cc
@@ -36,13 +36,14 @@ const int32 RenderViewFakeResourcesTest::kViewId = 5;
 RenderViewFakeResourcesTest::RenderViewFakeResourcesTest() {}
 RenderViewFakeResourcesTest::~RenderViewFakeResourcesTest() {}
 
-void RenderViewFakeResourcesTest::OnMessageReceived(
+bool RenderViewFakeResourcesTest::OnMessageReceived(
     const IPC::Message& message) {
   IPC_BEGIN_MESSAGE_MAP(RenderViewFakeResourcesTest, message)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
     IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopLoading, OnDidStopLoading)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource)
   IPC_END_MESSAGE_MAP()
+  return true;
 }
 
 bool RenderViewFakeResourcesTest::Visit(RenderView* render_view) {
diff --git a/chrome/renderer/safe_browsing/render_view_fake_resources_test.h b/chrome/renderer/safe_browsing/render_view_fake_resources_test.h
index 953b0cbbe5d3e48760455ea2322590b878c23be9..a92fb285c5f73a979faac4784b54bba8ad1b1d3c 100644
--- a/chrome/renderer/safe_browsing/render_view_fake_resources_test.h
+++ b/chrome/renderer/safe_browsing/render_view_fake_resources_test.h
@@ -71,7 +71,7 @@ class RenderViewFakeResourcesTest : public ::testing::Test,
                                     public RenderViewVisitor {
  public:
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
   // RenderViewVisitor implementation.
   virtual bool Visit(RenderView* render_view);
diff --git a/chrome/renderer/speech_input_dispatcher.h b/chrome/renderer/speech_input_dispatcher.h
index 09133d25bf6cd83a27b7b9494e93e2a19508a4bb..e9932268b7630a84fcc201145c15149b4be56c1c 100644
--- a/chrome/renderer/speech_input_dispatcher.h
+++ b/chrome/renderer/speech_input_dispatcher.h
@@ -7,7 +7,7 @@
 
 #include "base/basictypes.h"
 #include "chrome/common/speech_input_result.h"
-#include "ipc/ipc_message.h"
+#include "ipc/ipc_channel.h"
 #include "third_party/WebKit/WebKit/chromium/public/WebSpeechInputController.h"
 
 class GURL;
@@ -21,13 +21,13 @@ struct WebRect;
 
 // SpeechInputDispatcher is a delegate for speech input messages used by WebKit.
 // It's the complement of SpeechInputDispatcherHost (owned by RenderViewHost).
-class SpeechInputDispatcher : public WebKit::WebSpeechInputController {
+class SpeechInputDispatcher : public WebKit::WebSpeechInputController,
+                              public IPC::Channel::Listener {
  public:
   SpeechInputDispatcher(RenderView* render_view,
                         WebKit::WebSpeechInputListener* listener);
 
-  // Called to possibly handle the incoming IPC message. Returns true if
-  // handled. Called in render thread.
+  // IPC::Channel::Listener implementation.
   bool OnMessageReceived(const IPC::Message& msg);
 
   // WebKit::WebSpeechInputController.
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 1b2e7d7d98271366ffbd77adf636095700c11d7a..e76977ff9aede43ccc738b4062c01a5b2546c757 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -424,9 +424,10 @@ void WebPluginDelegateProxy::InstallMissingPlugin() {
   Send(new PluginMsg_InstallMissingPlugin(instance_id_));
 }
 
-void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
+bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
   child_process_logging::SetActiveURL(page_url_);
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg)
     IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow)
 #if defined(OS_WIN)
@@ -478,9 +479,10 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
 #endif
     IPC_MESSAGE_HANDLER(PluginHostMsg_URLRedirectResponse,
                         OnURLRedirectResponse)
-
-    IPC_MESSAGE_UNHANDLED_ERROR()
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  DCHECK(handled);
+  return handled;
 }
 
 void WebPluginDelegateProxy::OnChannelError() {
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index 30e212e034827f3e7041550d020de4521b8c8f87..49bcc703a89239534c610fd77da849d19f758fda 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -95,7 +95,7 @@ class WebPluginDelegateProxy
 #endif
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
   // IPC::Message::Sender implementation:
diff --git a/chrome/renderer/websharedworker_proxy.cc b/chrome/renderer/websharedworker_proxy.cc
index 8c79cb8fd7069dd2d10ad5a5456d0f34fd54d92d..84043d8cf1fba7a346c9d14c873ebfa254710b93 100644
--- a/chrome/renderer/websharedworker_proxy.cc
+++ b/chrome/renderer/websharedworker_proxy.cc
@@ -67,10 +67,13 @@ void WebSharedWorkerProxy::connect(WebKit::WebMessagePortChannel* channel,
   }
 }
 
-void WebSharedWorkerProxy::OnMessageReceived(const IPC::Message& message) {
+bool WebSharedWorkerProxy::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerProxy, message)
     IPC_MESSAGE_HANDLER(ViewMsg_WorkerCreated, OnWorkerCreated)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void WebSharedWorkerProxy::OnWorkerCreated() {
diff --git a/chrome/renderer/websharedworker_proxy.h b/chrome/renderer/websharedworker_proxy.h
index 78b1167c844ce3adf358d80e18b65a0cbee47ef5..d81826431dbe8d172a82f941014e8004478dcba3 100644
--- a/chrome/renderer/websharedworker_proxy.h
+++ b/chrome/renderer/websharedworker_proxy.h
@@ -41,7 +41,7 @@ class WebSharedWorkerProxy : public WebKit::WebSharedWorker,
   virtual void clientDestroyed();
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
  private:
   void OnWorkerCreated();
diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc
index abbb51f7828d2e42322ba3c2bbf8924a756db749..3ae174922cb05deeaa09e2064f115b32391e1c27 100644
--- a/chrome/renderer/webworker_proxy.cc
+++ b/chrome/renderer/webworker_proxy.cc
@@ -84,10 +84,11 @@ void WebWorkerProxy::workerObjectDestroyed() {
 void WebWorkerProxy::clientDestroyed() {
 }
 
-void WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
+bool WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
   if (!client_)
-    return;
+    return false;
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebWorkerProxy, message)
     IPC_MESSAGE_HANDLER(ViewMsg_WorkerCreated, OnWorkerCreated)
     IPC_MESSAGE_HANDLER(WorkerMsg_PostMessage, OnPostMessage)
@@ -105,7 +106,9 @@ void WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
     IPC_MESSAGE_FORWARD(WorkerHostMsg_WorkerContextDestroyed,
                         static_cast<WebCommonWorkerClient*>(client_),
                         WebCommonWorkerClient::workerContextDestroyed)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void WebWorkerProxy::OnWorkerCreated() {
diff --git a/chrome/renderer/webworker_proxy.h b/chrome/renderer/webworker_proxy.h
index 556f3dc08703c09346eea3011c4d4c18e260e6fa..4b51b4faf6baa489243b42fa9a273147611eaa4a 100644
--- a/chrome/renderer/webworker_proxy.h
+++ b/chrome/renderer/webworker_proxy.h
@@ -43,7 +43,7 @@ class WebWorkerProxy : public WebKit::WebWorker, private WebWorkerBase {
   virtual void clientDestroyed();
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
 
  private:
   void CancelCreation();
diff --git a/chrome/service/service_ipc_server.cc b/chrome/service/service_ipc_server.cc
index c7280c323b75b578902e744b5be1cce14d82423f..aa4d8ec2b7d705221516c7cce7c6074372bb093b 100644
--- a/chrome/service/service_ipc_server.cc
+++ b/chrome/service/service_ipc_server.cc
@@ -77,7 +77,8 @@ bool ServiceIPCServer::Send(IPC::Message* msg) {
   return channel_->Send(msg);
 }
 
-void ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
+bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg)
     IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxy,
                         OnEnableCloudPrintProxy)
@@ -100,7 +101,9 @@ void ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(ServiceMsg_Hello, OnHello);
     IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown);
     IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable);
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void ServiceIPCServer::OnEnableCloudPrintProxy(const std::string& lsid) {
diff --git a/chrome/service/service_ipc_server.h b/chrome/service/service_ipc_server.h
index af19f7baa9b2b4899f5fb4bc3c1b1cbcf783ec03..bff4f455c2f7acbaaa8fa681499f4ae4e514fcc2 100644
--- a/chrome/service/service_ipc_server.h
+++ b/chrome/service/service_ipc_server.h
@@ -35,7 +35,7 @@ class ServiceIPCServer : public IPC::Channel::Listener,
 
  private:
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc
index d6b4dbec0ace48298d5493071e4201a8d582a633..859e7259f2e404d2ed596e64a3d395da6837762b 100644
--- a/chrome/service/service_utility_process_host.cc
+++ b/chrome/service/service_utility_process_host.cc
@@ -128,7 +128,7 @@ void ServiceUtilityProcessHost::OnChildDied() {
   ServiceChildProcessHost::OnChildDied();
 }
 
-void ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
+bool ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
   bool msg_is_ok = false;
   IPC_BEGIN_MESSAGE_MAP_EX(ServiceUtilityProcessHost, message, msg_is_ok)
 #if defined(OS_WIN)  // This hack is Windows-specific.
@@ -138,6 +138,7 @@ void ServiceUtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
                         OnRenderPDFPagesToMetafileSucceeded)
     IPC_MESSAGE_UNHANDLED(msg_is_ok__ = MessageForClient(message))
   IPC_END_MESSAGE_MAP_EX()
+  return true;
 }
 
 bool ServiceUtilityProcessHost::MessageForClient(const IPC::Message& message) {
@@ -172,8 +173,9 @@ void ServiceUtilityProcessHost::OnRenderPDFPagesToMetafileSucceeded(
   waiting_for_reply_ = false;
 }
 
-void ServiceUtilityProcessHost::Client::OnMessageReceived(
+bool ServiceUtilityProcessHost::Client::OnMessageReceived(
     const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ServiceUtilityProcessHost, message)
     IPC_MESSAGE_HANDLER(UtilityHostMsg_RenderPDFPagesToMetafile_Failed,
                         Client::OnRenderPDFPagesToMetafileFailed)
@@ -181,7 +183,9 @@ void ServiceUtilityProcessHost::Client::OnMessageReceived(
                         Client::OnGetPrinterCapsAndDefaultsSucceeded)
     IPC_MESSAGE_HANDLER(UtilityHostMsg_GetPrinterCapsAndDefaults_Failed,
                         Client::OnGetPrinterCapsAndDefaultsFailed)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP_EX()
+  return handled;
 }
 
 void ServiceUtilityProcessHost::Client::MetafileAvailable(
diff --git a/chrome/service/service_utility_process_host.h b/chrome/service/service_utility_process_host.h
index 54e039cff7ab68e619329517b5f5ebf252a7cd7b..b770e1a2e008a831ad2fc2bdeb474e9fe878aea7 100644
--- a/chrome/service/service_utility_process_host.h
+++ b/chrome/service/service_utility_process_host.h
@@ -80,7 +80,7 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost {
     friend class base::RefCountedThreadSafe<Client>;
     friend class ServiceUtilityProcessHost;
 
-    void OnMessageReceived(const IPC::Message& message);
+    bool OnMessageReceived(const IPC::Message& message);
     // Invoked when a metafile file is ready.
     void MetafileAvailable(const FilePath& metafile_path,
                            int highest_rendered_page_number);
@@ -122,7 +122,7 @@ class ServiceUtilityProcessHost : public ServiceChildProcessHost {
   bool StartProcess(bool no_sandbox, const FilePath& exposed_dir);
 
   // IPC messages:
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   // Called when at least one page in the specified PDF has been rendered
   // successfully into metafile_path_;
   void OnRenderPDFPagesToMetafileSucceeded(int highest_rendered_page_number);
diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc
index bf00ea64a3925d33ee2009b7c41bfb235e592784..cf9391dfff1db49a3cc035803660a98e60c6b2a0 100644
--- a/chrome/test/automation/automation_proxy.cc
+++ b/chrome/test/automation/automation_proxy.cc
@@ -42,17 +42,16 @@ class AutomationMessageFilter : public IPC::ChannelProxy::MessageFilter {
   // the message be handled in the default way.
   virtual bool OnMessageReceived(const IPC::Message& message) {
     bool handled = true;
-
     IPC_BEGIN_MESSAGE_MAP(AutomationMessageFilter, message)
       IPC_MESSAGE_HANDLER_GENERIC(AutomationMsg_Hello,
-                                  OnAutomationHello(message));
+                                  OnAutomationHello(message))
       IPC_MESSAGE_HANDLER_GENERIC(
-        AutomationMsg_InitialLoadsComplete, server_->SignalInitialLoads());
+        AutomationMsg_InitialLoadsComplete, server_->SignalInitialLoads())
       IPC_MESSAGE_HANDLER(AutomationMsg_InitialNewTabUILoadComplete,
-                          NewTabLoaded);
+                          NewTabLoaded)
       IPC_MESSAGE_HANDLER_GENERIC(
-        AutomationMsg_InvalidateHandle, server_->InvalidateHandle(message));
-      IPC_MESSAGE_UNHANDLED(handled = false);
+        AutomationMsg_InvalidateHandle, server_->InvalidateHandle(message))
+      IPC_MESSAGE_UNHANDLED(handled = false)
     IPC_END_MESSAGE_MAP()
 
     return handled;
@@ -379,10 +378,11 @@ void AutomationProxy::Disconnect() {
   channel_.reset();
 }
 
-void AutomationProxy::OnMessageReceived(const IPC::Message& msg) {
+bool AutomationProxy::OnMessageReceived(const IPC::Message& msg) {
   // This won't get called unless AutomationProxy is run from
   // inside a message loop.
   NOTREACHED();
+  return false;
 }
 
 void AutomationProxy::OnChannelError() {
diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h
index b0cd74c797e9f00b6b5aa7761809137398e420fc..ee770160beeb292bb43ae345cda1f67cbde5b618 100644
--- a/chrome/test/automation/automation_proxy.h
+++ b/chrome/test/automation/automation_proxy.h
@@ -70,7 +70,7 @@ class AutomationProxy : public IPC::Channel::Listener,
                          bool use_named_interface);
 
   // IPC callback
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
   // Close the automation IPC channel.
diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc
index 9c36fe18c182ebdecbd9d23ff363c882fa0db519..8568e5ed87c18df9f9ffb0e2ee86ca5a8b12094d 100644
--- a/chrome/test/automation/automation_proxy_uitest.cc
+++ b/chrome/test/automation/automation_proxy_uitest.cc
@@ -762,7 +762,8 @@ const AutomationURLResponse ExternalTabUITestMockClient::http_200(
     "",
     0);
 
-void ExternalTabUITestMockClient::OnMessageReceived(const IPC::Message& msg) {
+bool ExternalTabUITestMockClient::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ExternalTabUITestMockClient, msg)
     IPC_MESSAGE_HANDLER(AutomationMsg_DidNavigate, OnDidNavigate)
     IPC_MESSAGE_HANDLER(AutomationMsg_ForwardMessageToExternalHost,
@@ -776,7 +777,9 @@ void ExternalTabUITestMockClient::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(AutomationMsg_OpenURL, OnOpenURL)
     IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged,
                         OnNavigationStateChanged)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 scoped_refptr<TabProxy> ExternalTabUITestMockClient::CreateHostWindowAndTab(
diff --git a/chrome/test/automation/automation_proxy_uitest.h b/chrome/test/automation/automation_proxy_uitest.h
index 35de19739b19e3a7316d8ac60a8834317a6261c4..6f87c4ea5acab5206b5d4b1a23fc0db60fe9eb89 100644
--- a/chrome/test/automation/automation_proxy_uitest.h
+++ b/chrome/test/automation/automation_proxy_uitest.h
@@ -101,7 +101,7 @@ class ExternalTabUITestMockClient : public AutomationProxy {
   gfx::NativeWindow host_window_;
 
   // Simple dispatcher to above OnXXX methods.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void InvalidateHandle(const IPC::Message& message);
 };
 
diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc
index dbf298c896774651d2b88b1831591afe6356f6a7..ce7ed16915d97ea8f8363bf3e93d4a3f1aa24b7e 100644
--- a/chrome/test/automation/tab_proxy.cc
+++ b/chrome/test/automation/tab_proxy.cc
@@ -790,10 +790,11 @@ void TabProxy::RemoveObserver(TabProxyDelegate* observer) {
 }
 
 // Called on Channel background thread, if TabMessages filter is installed.
-void TabProxy::OnMessageReceived(const IPC::Message& message) {
+bool TabProxy::OnMessageReceived(const IPC::Message& message) {
   AutoLock lock(list_lock_);
   FOR_EACH_OBSERVER(TabProxyDelegate, observers_list_,
                     OnMessageReceived(this, message));
+  return true;
 }
 
 void TabProxy::OnChannelError() {
diff --git a/chrome/test/automation/tab_proxy.h b/chrome/test/automation/tab_proxy.h
index 8c70abd3969b0501754bbf6e98f5fe06baf71ef4..82f65acd2f8d4c7082931154a22c69c0e7dc95de 100644
--- a/chrome/test/automation/tab_proxy.h
+++ b/chrome/test/automation/tab_proxy.h
@@ -405,7 +405,7 @@ class TabProxy : public AutomationResourceProxy,
   // Calls delegates
   void AddObserver(TabProxyDelegate* observer);
   void RemoveObserver(TabProxyDelegate* observer);
-  void OnMessageReceived(const IPC::Message& message);
+  bool OnMessageReceived(const IPC::Message& message);
   void OnChannelError();
  protected:
   virtual ~TabProxy();
diff --git a/chrome/utility/utility_thread.cc b/chrome/utility/utility_thread.cc
index baf831f61c0794308afad3da494524e28445f282..2349f07bf47ab059b8a485ab91d5ae2843acc5ea 100644
--- a/chrome/utility/utility_thread.cc
+++ b/chrome/utility/utility_thread.cc
@@ -51,7 +51,8 @@ UtilityThread::UtilityThread()
 UtilityThread::~UtilityThread() {
 }
 
-void UtilityThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool UtilityThread::OnControlMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(UtilityThread, msg)
     IPC_MESSAGE_HANDLER(UtilityMsg_UnpackExtension, OnUnpackExtension)
     IPC_MESSAGE_HANDLER(UtilityMsg_UnpackWebResource, OnUnpackWebResource)
@@ -65,7 +66,9 @@ void UtilityThread::OnControlMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(UtilityMsg_BatchMode_Finished, OnBatchModeFinished)
     IPC_MESSAGE_HANDLER(UtilityMsg_GetPrinterCapsAndDefaults,
                         OnGetPrinterCapsAndDefaults)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void UtilityThread::OnUnpackExtension(const FilePath& extension_path) {
diff --git a/chrome/utility/utility_thread.h b/chrome/utility/utility_thread.h
index 187f914dc61eb03bdefd87c143373f4dbf8b0223..ce4cc25cb1589751e3cac6e8832c62cbc7682918 100644
--- a/chrome/utility/utility_thread.h
+++ b/chrome/utility/utility_thread.h
@@ -38,7 +38,7 @@ class UtilityThread : public ChildThread {
 
  private:
   // IPC messages
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
   void OnUnpackExtension(const FilePath& extension_path);
 
   // IPC messages for web resource service.
diff --git a/chrome/worker/websharedworker_stub.cc b/chrome/worker/websharedworker_stub.cc
index 8cb167a01df42b3f4614ffdb0881a1ab129bf0b9..0c03ba082262c3a8f786b62f6db2f68c8f0302ab 100644
--- a/chrome/worker/websharedworker_stub.cc
+++ b/chrome/worker/websharedworker_stub.cc
@@ -26,13 +26,16 @@ WebSharedWorkerStub::~WebSharedWorkerStub() {
   impl_->clientDestroyed();
 }
 
-void WebSharedWorkerStub::OnMessageReceived(const IPC::Message& message) {
+bool WebSharedWorkerStub::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerStub, message)
     IPC_MESSAGE_HANDLER(WorkerMsg_StartWorkerContext, OnStartWorkerContext)
     IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext,
                         OnTerminateWorkerContext)
     IPC_MESSAGE_HANDLER(WorkerMsg_Connect, OnConnect)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void WebSharedWorkerStub::OnChannelError() {
diff --git a/chrome/worker/websharedworker_stub.h b/chrome/worker/websharedworker_stub.h
index b9cb60ce4d5ec83cca91dd449261b19866c09805..04f07afe23a5210406a4844863e8497fbac679e4 100644
--- a/chrome/worker/websharedworker_stub.h
+++ b/chrome/worker/websharedworker_stub.h
@@ -22,7 +22,7 @@ class WebSharedWorkerStub : public WebWorkerStubBase {
                       const WorkerAppCacheInitInfo& appcache_init_info);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelError();
 
   virtual const GURL& url() const;
diff --git a/chrome/worker/webworker_stub.cc b/chrome/worker/webworker_stub.cc
index cd58cab1b6056ca87cd8a1354db9e5b29b15ddd7..a3d3ba452ab3b26f41a9c1bc9c7985ae60652f83 100644
--- a/chrome/worker/webworker_stub.cc
+++ b/chrome/worker/webworker_stub.cc
@@ -60,10 +60,11 @@ const GURL& WebWorkerStub::url() const {
   return url_;
 }
 
-void WebWorkerStub::OnMessageReceived(const IPC::Message& message) {
+bool WebWorkerStub::OnMessageReceived(const IPC::Message& message) {
   if (!impl_)
-    return;
+    return false;
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebWorkerStub, message)
     IPC_MESSAGE_FORWARD(WorkerMsg_StartWorkerContext, impl_,
                         WebWorker::startWorkerContext)
@@ -72,7 +73,9 @@ void WebWorkerStub::OnMessageReceived(const IPC::Message& message) {
     IPC_MESSAGE_HANDLER(WorkerMsg_PostMessage, OnPostMessage)
     IPC_MESSAGE_FORWARD(WorkerMsg_WorkerObjectDestroyed, impl_,
                         WebWorker::workerObjectDestroyed)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void WebWorkerStub::OnTerminateWorkerContext() {
diff --git a/chrome/worker/webworker_stub.h b/chrome/worker/webworker_stub.h
index 76e105848c6dd436d62b0390aabcfbe549ba60b1..cc0d75df42f6ebd19547209e33b7e28d8f2d27f4 100644
--- a/chrome/worker/webworker_stub.h
+++ b/chrome/worker/webworker_stub.h
@@ -22,7 +22,7 @@ class WebWorkerStub : public WebWorkerStubBase {
                 const WorkerAppCacheInitInfo& appcache_init_info);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelError();
 
   virtual const GURL& url() const;
diff --git a/chrome/worker/worker_thread.cc b/chrome/worker/worker_thread.cc
index cafd482ed2c2327bc6054f5758354e7dd0f00ed2..f7a1e4a4c004a72cc086a707f5b573f1c9db1503 100644
--- a/chrome/worker/worker_thread.cc
+++ b/chrome/worker/worker_thread.cc
@@ -77,14 +77,17 @@ WorkerThread* WorkerThread::current() {
   return lazy_tls.Pointer()->Get();
 }
 
-void WorkerThread::OnControlMessageReceived(const IPC::Message& msg) {
+bool WorkerThread::OnControlMessageReceived(const IPC::Message& msg) {
   // Appcache messages are handled by a delegate.
   if (appcache_dispatcher_->OnMessageReceived(msg))
-    return;
+    return true;
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WorkerThread, msg)
     IPC_MESSAGE_HANDLER(WorkerProcessMsg_CreateWorker, OnCreateWorker)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void WorkerThread::OnCreateWorker(
diff --git a/chrome/worker/worker_thread.h b/chrome/worker/worker_thread.h
index da154b4aed2286b02022094d427005f3fe46c5dd..1bde9b5960ea440a1639133f88e999e50ccce5db 100644
--- a/chrome/worker/worker_thread.h
+++ b/chrome/worker/worker_thread.h
@@ -35,7 +35,7 @@ class WorkerThread : public ChildThread {
   }
 
  private:
-  virtual void OnControlMessageReceived(const IPC::Message& msg);
+  virtual bool OnControlMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError();
 
   void OnCreateWorker(const WorkerProcessMsg_CreateWorker_Params& params);
diff --git a/chrome_frame/cfproxy.h b/chrome_frame/cfproxy.h
index ae404b2ab426dc2a922c2c2ca7421e4dcac71793..b32bf78b2660fa6516530610a35b55a9b0ed55f2 100644
--- a/chrome_frame/cfproxy.h
+++ b/chrome_frame/cfproxy.h
@@ -148,9 +148,6 @@ class ChromeProxyDelegate : public IPC::Channel::Listener {
     CHANNEL_ERROR
   };
 
-  // IPC::Channel::Listener.
-  void OnMessageReceived(const IPC::Message& message) = 0;
-
   virtual void Connected(ChromeProxy* proxy) = 0;
   virtual void Disconnected() = 0;
   virtual void PeerLost(ChromeProxy* proxy, DisconnectReason reason) = 0;
diff --git a/chrome_frame/cfproxy_private.h b/chrome_frame/cfproxy_private.h
index 6ec0080c96b719d2288ce528df0fd378674ea1a7..165e2310c22ef6615e49bd8155c08e0bca825bb2 100644
--- a/chrome_frame/cfproxy_private.h
+++ b/chrome_frame/cfproxy_private.h
@@ -163,7 +163,7 @@ class CFProxy : public Interface2IPCMessage,
 
   //////////////////////////////////////////////////////////////////////////
   // IPC::Channel::Listener
-  virtual void OnMessageReceived(const IPC::Message& message);
+  virtual bool OnMessageReceived(const IPC::Message& message);
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnChannelError();
 
diff --git a/chrome_frame/cfproxy_proxy.cc b/chrome_frame/cfproxy_proxy.cc
index 0f59d8a5699aa907ecb05b4deaaf593427bee105..46ac821a568d1c37fb3ef43c5891fb4d2c20c1c1 100644
--- a/chrome_frame/cfproxy_proxy.cc
+++ b/chrome_frame/cfproxy_proxy.cc
@@ -208,11 +208,11 @@ void CFProxy::Tab_RunUnloadHandlers(int tab) {
 }
 
 // IPC::Channel::Listener
-void CFProxy::OnMessageReceived(const IPC::Message& message) {
+bool CFProxy::OnMessageReceived(const IPC::Message& message) {
   // Handle sync message reply.
   bool done = sync_dispatcher_.OnReplyReceived(&message);
   if (done)
-    return;
+    return true;
 
   // Handle tab related message.
   ChromeProxyDelegate* d = Tab2Delegate(message.routing_id());
@@ -220,6 +220,7 @@ void CFProxy::OnMessageReceived(const IPC::Message& message) {
     return d->OnMessageReceived(message);
 
   DLOG(WARNING) << "Unknown message received!";
+  return false;
 }
 
 void CFProxy::OnChannelConnected(int32 peer_pid) {
diff --git a/chrome_frame/cfproxy_test.cc b/chrome_frame/cfproxy_test.cc
index d6be8b17cec7f4b50a342d6e5146b884a0bca058..46e716daae02b55a6b710fe1954fcdc3ccf1f9c7 100644
--- a/chrome_frame/cfproxy_test.cc
+++ b/chrome_frame/cfproxy_test.cc
@@ -1,3 +1,4 @@
+
 // Copyright (c) 2010 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.
@@ -28,7 +29,7 @@ struct MockFactory : public ChromeProxyFactory {
 };
 
 struct MockChromeProxyDelegate : public ChromeProxyDelegate {
-  MOCK_METHOD1(OnMessageReceived, void(const IPC::Message& message));
+  MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message& message));
   MOCK_METHOD1(Connected, void(ChromeProxy* proxy));
   MOCK_METHOD2(PeerLost, void(ChromeProxy*, enum DisconnectReason reason));
   MOCK_METHOD0(Disconnected, void());
diff --git a/chrome_frame/chrome_frame_delegate.cc b/chrome_frame/chrome_frame_delegate.cc
index cd54c5f15f0df6f967f4231fd752a8d2778d9d21..a2e84b60dd05fbab67ededafcc93ac6983562666 100644
--- a/chrome_frame/chrome_frame_delegate.cc
+++ b/chrome_frame/chrome_frame_delegate.cc
@@ -33,13 +33,14 @@ bool ChromeFrameDelegateImpl::IsTabMessage(const IPC::Message& message) {
   return is_tab_message;
 }
 
-void ChromeFrameDelegateImpl::OnMessageReceived(const IPC::Message& msg) {
+bool ChromeFrameDelegateImpl::OnMessageReceived(const IPC::Message& msg) {
   if (!IsValid()) {
     DLOG(WARNING) << __FUNCTION__
                   << " Msgs received for a NULL automation client instance";
-    return;
+    return false;
   }
 
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ChromeFrameDelegateImpl, msg)
     IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged,
                         OnNavigationStateChanged)
@@ -66,5 +67,8 @@ void ChromeFrameDelegateImpl::OnMessageReceived(const IPC::Message& msg) {
         OnGoToHistoryEntryOffset)
     IPC_MESSAGE_HANDLER(AutomationMsg_GetCookiesFromHost, OnGetCookiesFromHost)
     IPC_MESSAGE_HANDLER(AutomationMsg_CloseExternalTab, OnCloseTab)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+
+  return handled;
 }
diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h
index 647f0d0cf61d88066b9f541c0941d86de3e813d2..1a0f34b60a7847a8b476a38712db0dfbb8b38c06 100644
--- a/chrome_frame/chrome_frame_delegate.h
+++ b/chrome_frame/chrome_frame_delegate.h
@@ -35,7 +35,7 @@ class ChromeFrameDelegate {
   virtual void OnGetEnabledExtensionsComplete(
       void* user_data,
       const std::vector<FilePath>& extension_directories) = 0;
-  virtual void OnMessageReceived(const IPC::Message& msg) = 0;
+  virtual bool OnMessageReceived(const IPC::Message& msg) = 0;
   virtual void OnChannelError() = 0;
 
   // This remains in interface since we call it if Navigate()
@@ -76,7 +76,7 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
       void* user_data,
       const std::vector<FilePath>& extension_directories) {}
   virtual void OnLoadFailed(int error_code, const std::string& url) {}
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual void OnChannelError() {}
 
   static bool IsTabMessage(const IPC::Message& message);
diff --git a/chrome_frame/external_tab.cc b/chrome_frame/external_tab.cc
index 99477ef3193fc294f0ac3ddcdfa396c2b6fb5df3..9be493569bd6e6e3ef0a74195f4677215cfe1cbb 100644
--- a/chrome_frame/external_tab.cc
+++ b/chrome_frame/external_tab.cc
@@ -34,7 +34,8 @@ ExternalTabProxy::~ExternalTabProxy() {
   Destroy();
 }
 
-void ExternalTabProxy::OnMessageReceived(const IPC::Message& message) {
+bool ExternalTabProxy::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ExternalTabProxy, message)
     IPC_MESSAGE_HANDLER(AutomationMsg_NavigationStateChanged,
                         OnNavigationStateChanged)
@@ -60,7 +61,9 @@ void ExternalTabProxy::OnMessageReceived(const IPC::Message& message) {
     IPC_MESSAGE_HANDLER(AutomationMsg_RequestGoToHistoryEntryOffset,
                         OnGoToHistoryOffset)
     IPC_MESSAGE_HANDLER(AutomationMsg_CloseExternalTab, OnTabClosed)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void ExternalTabProxy::Init() {
diff --git a/chrome_frame/external_tab.h b/chrome_frame/external_tab.h
index c3dcbabc9305a3144a7266ce7f74161e00bf4262..4fbb5d336691ae17efee7c1aa0481452c4180435 100644
--- a/chrome_frame/external_tab.h
+++ b/chrome_frame/external_tab.h
@@ -94,7 +94,7 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
 #endif
 
   // IPC::Channel::Listener implementation.
-  void OnMessageReceived(const IPC::Message& message);
+  bool OnMessageReceived(const IPC::Message& message);
 
   //
   virtual void CreateTab(const CreateTabParams& create_params,
diff --git a/chrome_frame/test/net/test_automation_provider.cc b/chrome_frame/test/net/test_automation_provider.cc
index 4b4d2a12992be9f83351cfabfafde26bab244523..c015d2b7a1b447f015a7453e1a351814b5a21342 100644
--- a/chrome_frame/test/net/test_automation_provider.cc
+++ b/chrome_frame/test/net/test_automation_provider.cc
@@ -48,11 +48,11 @@ TestAutomationProvider::~TestAutomationProvider() {
   g_provider_instance_ = NULL;
 }
 
-void TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) {
+bool TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) {
   if (automation_resource_message_filter_->OnMessageReceived(msg))
-    return;  // Message handled by the filter.
+    return true;  // Message handled by the filter.
 
-  __super::OnMessageReceived(msg);
+  return __super::OnMessageReceived(msg);
 }
 
 // IPC override to grab the tab handle.
diff --git a/chrome_frame/test/net/test_automation_provider.h b/chrome_frame/test/net/test_automation_provider.h
index bc98b3a3cd0004783c475df218523ac82f08402c..209a069c90c123e567917874f3c2ab2c45803205 100644
--- a/chrome_frame/test/net/test_automation_provider.h
+++ b/chrome_frame/test/net/test_automation_provider.h
@@ -36,7 +36,7 @@ class TestAutomationProvider
   virtual ~TestAutomationProvider();
 
   // AutomationProvider overrides.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
   virtual bool Send(IPC::Message* msg);
 
   // Protocol factory for handling http/https requests over automation.
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
index c257a8e9f9f753509f4e3b3d46cf1e59e14e5fd8..3b8afd8b8f9cc6f95f7f22d55ebfd37361fc50bf 100644
--- a/ipc/ipc_channel.h
+++ b/ipc/ipc_channel.h
@@ -39,8 +39,9 @@ class Channel : public Message::Sender {
    public:
     virtual ~Listener() {}
 
-    // Called when a message is received.
-    virtual void OnMessageReceived(const Message& message) = 0;
+    // Called when a message is received.  Returns true iff the message was
+    // handled.
+    virtual bool OnMessageReceived(const Message& message) = 0;
 
     // Called when the channel is connected and we have received the internal
     // Hello message from the peer.
diff --git a/ipc/ipc_channel_posix_unittest.cc b/ipc/ipc_channel_posix_unittest.cc
index 09c635fe53a793a4b042d55c6a1f8dc96791cd55..459aafb0276a3b8b9e0f5da4f9efbed7525a9224 100644
--- a/ipc/ipc_channel_posix_unittest.cc
+++ b/ipc/ipc_channel_posix_unittest.cc
@@ -43,10 +43,11 @@ class IPCChannelPosixTestListener : public IPC::Channel::Listener {
 
   virtual ~IPCChannelPosixTestListener() {}
 
-  virtual void OnMessageReceived(const IPC::Message& message) {
+  virtual bool OnMessageReceived(const IPC::Message& message) {
     EXPECT_EQ(message.type(), QUIT_MESSAGE);
     status_ = MESSAGE_RECEIVED;
     QuitRunLoop();
+    return true;
   }
 
   virtual void OnChannelConnected(int32 peer_pid) {
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc
index aba6bf5ed513beacf235e49b5c864f67b175364f..b9533e69c4ca5e37775f7e178276e32d90a29d10 100644
--- a/ipc/ipc_channel_proxy.cc
+++ b/ipc/ipc_channel_proxy.cc
@@ -96,20 +96,22 @@ bool ChannelProxy::Context::TryFilters(const Message& message) {
 }
 
 // Called on the IPC::Channel thread
-void ChannelProxy::Context::OnMessageReceived(const Message& message) {
+bool ChannelProxy::Context::OnMessageReceived(const Message& message) {
   // First give a chance to the filters to process this message.
   if (!TryFilters(message))
     OnMessageReceivedNoFilter(message);
+  return true;
 }
 
 // Called on the IPC::Channel thread
-void ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
+bool ChannelProxy::Context::OnMessageReceivedNoFilter(const Message& message) {
   // NOTE: This code relies on the listener's message loop not going away while
   // this thread is active.  That should be a reasonable assumption, but it
   // feels risky.  We may want to invent some more indirect way of referring to
   // a MessageLoop if this becomes a problem.
   listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
       this, &Context::OnDispatchMessage, message));
+  return true;
 }
 
 // Called on the IPC::Channel thread
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h
index a256ab6cb68602ae20ac1627db966f7a88553cc4..82a243b015e9200fda96226362a8e77d27b6ebae 100644
--- a/ipc/ipc_channel_proxy.h
+++ b/ipc/ipc_channel_proxy.h
@@ -176,12 +176,12 @@ class ChannelProxy : public Message::Sender {
     virtual ~Context() { }
 
     // IPC::Channel::Listener methods:
-    virtual void OnMessageReceived(const Message& message);
+    virtual bool OnMessageReceived(const Message& message);
     virtual void OnChannelConnected(int32 peer_pid);
     virtual void OnChannelError();
 
     // Like OnMessageReceived but doesn't try the filters.
-    void OnMessageReceivedNoFilter(const Message& message);
+    bool OnMessageReceivedNoFilter(const Message& message);
 
     // Gives the filters a chance at processing |message|.
     // Returns true if the message was processed, false otherwise.
diff --git a/ipc/ipc_fuzzing_tests.cc b/ipc/ipc_fuzzing_tests.cc
index 4b5e9388feac142d701e33ec9c47c7a0ceeae475..5dd916f900d3e50b8f1f3ac208410518b0ed9182 100644
--- a/ipc/ipc_fuzzing_tests.cc
+++ b/ipc/ipc_fuzzing_tests.cc
@@ -158,7 +158,7 @@ class FuzzerServerListener : public SimpleListener {
  public:
   FuzzerServerListener() : message_count_(2), pending_messages_(0) {
   }
-  virtual void OnMessageReceived(const IPC::Message& msg) {
+  virtual bool OnMessageReceived(const IPC::Message& msg) {
     if (msg.routing_id() == MSG_ROUTING_CONTROL) {
       ++pending_messages_;
       IPC_BEGIN_MESSAGE_MAP(FuzzerServerListener, msg)
@@ -170,6 +170,7 @@ class FuzzerServerListener : public SimpleListener {
         ReplyMsgNotHandled(msg.type());
       }
     }
+    return true;
   }
 
  private:
@@ -221,9 +222,10 @@ class FuzzerClientListener : public SimpleListener {
   FuzzerClientListener() : last_msg_(NULL) {
   }
 
-  virtual void OnMessageReceived(const IPC::Message& msg) {
+  virtual bool OnMessageReceived(const IPC::Message& msg) {
     last_msg_ = new IPC::Message(msg);
     MessageLoop::current()->Quit();
+    return true;
   }
 
   bool ExpectMessage(int value, uint32 type_id) {
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h
index 504be00cfac55dfff6b7821223d3a93408209e7a..af2901a0277321ba3a8f4348f4c4d5ff4c6744a5 100644
--- a/ipc/ipc_message_macros.h
+++ b/ipc/ipc_message_macros.h
@@ -1163,23 +1163,22 @@ LogFunctionMap g_log_function_mapping;
 // Prefer to use the IPC_BEGIN_MESSAGE_MAP_EX to the older macros since they
 // allow you to detect when a message could not be de-serialized. Usage:
 //
-//   void MyClass::OnMessageReceived(const IPC::Message& msg) {
+//   bool MyClass::OnMessageReceived(const IPC::Message& msg) {
+//     bool handled = true;
 //     bool msg_is_good = false;
 //     IPC_BEGIN_MESSAGE_MAP_EX(MyClass, msg, msg_is_good)
 //       IPC_MESSAGE_HANDLER(MsgClassOne, OnMsgClassOne)
 //       ...more handlers here ...
 //       IPC_MESSAGE_HANDLER(MsgClassTen, OnMsgClassTen)
+//       IPC_MESSAGE_UNHANDLED(handled = false)
 //     IPC_END_MESSAGE_MAP_EX()
 //     if (!msg_is_good) {
 //       // Signal error here or terminate offending process.
 //     }
+//     return handled;
 //   }
 
 
-#define IPC_DEFINE_MESSAGE_MAP(class_name) \
-void class_name::OnMessageReceived(const IPC::Message& msg) \
-  IPC_BEGIN_MESSAGE_MAP(class_name, msg)
-
 #define IPC_BEGIN_MESSAGE_MAP_EX(class_name, msg, msg_is_ok) \
   { \
     typedef class_name _IpcMessageHandlerClass; \
diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc
index 809f4f576e2d438c0627954c46a3223332d4705c..3b845f8cf3c24b6acfae103e02ddd686b9de03e4 100644
--- a/ipc/ipc_send_fds_test.cc
+++ b/ipc/ipc_send_fds_test.cc
@@ -51,20 +51,20 @@ class MyChannelDescriptorListener : public IPC::Channel::Listener {
       : expected_inode_num_(expected_inode_num),
         num_fds_received_(0) {}
 
-  virtual void OnMessageReceived(const IPC::Message& message) {
+  virtual bool OnMessageReceived(const IPC::Message& message) {
     void* iter = NULL;
 
     ++num_fds_received_;
     base::FileDescriptor descriptor;
 
-    ASSERT_TRUE(
-        IPC::ParamTraits<base::FileDescriptor>::Read(
-            &message, &iter, &descriptor));
+    IPC::ParamTraits<base::FileDescriptor>::Read(
+            &message, &iter, &descriptor);
 
     VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_);
     if (num_fds_received_ == kNumFDsToSend) {
       MessageLoop::current()->Quit();
     }
+    return true;
   }
 
   virtual void OnChannelError() {
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
index 7425a9be2d11cedd3715719e05cdd65497d25db4..79b1e6019be6ec4e2e148a8ad89ec7d5a4523cb3 100644
--- a/ipc/ipc_sync_channel.cc
+++ b/ipc/ipc_sync_channel.cc
@@ -285,22 +285,22 @@ void SyncChannel::SyncContext::Clear() {
   Context::Clear();
 }
 
-void SyncChannel::SyncContext::OnMessageReceived(const Message& msg) {
+bool SyncChannel::SyncContext::OnMessageReceived(const Message& msg) {
   // Give the filters a chance at processing this message.
   if (TryFilters(msg))
-    return;
+    return true;
 
   if (TryToUnblockListener(&msg))
-    return;
+    return true;
 
   if (msg.should_unblock()) {
     received_sync_msgs_->QueueMessage(msg, this);
-    return;
+    return true;
   }
 
   if (msg.is_reply()) {
     received_sync_msgs_->QueueReply(msg, this);
-    return;
+    return true;
   }
 
   return Context::OnMessageReceivedNoFilter(msg);
diff --git a/ipc/ipc_sync_channel.h b/ipc/ipc_sync_channel.h
index fce2e3854e9fb8a43ba646081a8295a17e0b0857..d1cef930c6c93b32f6dee138b0b7ad8b9a0deedd 100644
--- a/ipc/ipc_sync_channel.h
+++ b/ipc/ipc_sync_channel.h
@@ -106,7 +106,7 @@ class SyncChannel : public ChannelProxy,
     virtual void Clear();
 
     // Called on the IPC thread.
-    virtual void OnMessageReceived(const Message& msg);
+    virtual bool OnMessageReceived(const Message& msg);
     virtual void OnChannelError();
     virtual void OnChannelOpened();
     virtual void OnChannelClosed();
diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc
index 772df0b7165e4686586f95ad2c68944da50ab4a7..e580ba4340291b14485dd1785ca55a114f4066ea 100644
--- a/ipc/ipc_sync_channel_unittest.cc
+++ b/ipc/ipc_sync_channel_unittest.cc
@@ -195,7 +195,7 @@ class Worker : public Channel::Listener, public Message::Sender {
     listener_event->Signal();
   }
 
-  void OnMessageReceived(const Message& message) {
+  bool OnMessageReceived(const Message& message) {
     IPC_BEGIN_MESSAGE_MAP(Worker, message)
      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
@@ -203,6 +203,7 @@ class Worker : public Channel::Listener, public Message::Sender {
      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelNestedTestMsg_String,
                                      OnNestedTestMsg)
     IPC_END_MESSAGE_MAP()
+    return true;
   }
 
   void StartThread(base::Thread* thread, MessageLoop::Type type) {
diff --git a/ipc/ipc_sync_message_unittest.cc b/ipc/ipc_sync_message_unittest.cc
index e64e0c33b4c3509fed2ee9753d04f476789f955a..9a72aa3aba95655bbe2ffdd16ee7d6979390492d 100644
--- a/ipc/ipc_sync_message_unittest.cc
+++ b/ipc/ipc_sync_message_unittest.cc
@@ -108,7 +108,7 @@ class TestMessageReceiver {
     return true;
   }
 
-  void OnMessageReceived(const IPC::Message& msg) {
+  bool OnMessageReceived(const IPC::Message& msg) {
     IPC_BEGIN_MESSAGE_MAP(TestMessageReceiver, msg)
       IPC_MESSAGE_HANDLER(Msg_C_0_1, On_0_1)
       IPC_MESSAGE_HANDLER(Msg_C_0_2, On_0_2)
@@ -137,6 +137,7 @@ class TestMessageReceiver {
       IPC_MESSAGE_HANDLER(Msg_R_3_3, On_3_3)
       IPC_MESSAGE_HANDLER(Msg_R_3_4, On_3_4)
     IPC_END_MESSAGE_MAP()
+    return true;
   }
 
 };
diff --git a/ipc/ipc_tests.cc b/ipc/ipc_tests.cc
index aee01f50efd39a799b71d26d6b4648289ed850b0..925aeab89e60f5ef93d6537611f0062d8e6c506d 100644
--- a/ipc/ipc_tests.cc
+++ b/ipc/ipc_tests.cc
@@ -182,7 +182,7 @@ static void Send(IPC::Message::Sender* sender, const char* text) {
 
 class MyChannelListener : public IPC::Channel::Listener {
  public:
-  virtual void OnMessageReceived(const IPC::Message& message) {
+  virtual bool OnMessageReceived(const IPC::Message& message) {
     IPC::MessageIterator iter(message);
 
     iter.NextInt();
@@ -196,6 +196,7 @@ class MyChannelListener : public IPC::Channel::Listener {
     } else {
       Send(sender_, "Foo");
     }
+    return true;
   }
 
   virtual void OnChannelError() {
@@ -291,7 +292,7 @@ class ChannelListenerWithOnConnectedSend : public IPC::Channel::Listener {
     SendNextMessage();
   }
 
-  virtual void OnMessageReceived(const IPC::Message& message) {
+  virtual bool OnMessageReceived(const IPC::Message& message) {
     IPC::MessageIterator iter(message);
 
     iter.NextInt();
@@ -299,6 +300,7 @@ class ChannelListenerWithOnConnectedSend : public IPC::Channel::Listener {
     const std::string big_string = iter.NextString();
     EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
     SendNextMessage();
+    return true;
   }
 
   virtual void OnChannelError() {
@@ -402,7 +404,7 @@ class ChannelReflectorListener : public IPC::Channel::Listener {
     std::cout << "Client Latency: " << latency_messages_ << std::endl;
   }
 
-  virtual void OnMessageReceived(const IPC::Message& message) {
+  virtual bool OnMessageReceived(const IPC::Message& message) {
     count_messages_++;
     IPC::MessageIterator iter(message);
     int time = iter.NextInt();
@@ -421,6 +423,7 @@ class ChannelReflectorListener : public IPC::Channel::Listener {
     msg->WriteInt(msgid);
     msg->WriteString(payload);
     channel_->Send(msg);
+    return true;
   }
  private:
   IPC::Channel *channel_;
@@ -446,7 +449,7 @@ class ChannelPerfListener : public IPC::Channel::Listener {
     std::cout << "Server Latency: " << latency_messages_ << std::endl;
   }
 
-  virtual void OnMessageReceived(const IPC::Message& message) {
+  virtual bool OnMessageReceived(const IPC::Message& message) {
     count_messages_++;
     // decode the string so this gets counted in the total time
     IPC::MessageIterator iter(message);
@@ -467,7 +470,7 @@ class ChannelPerfListener : public IPC::Channel::Listener {
       msg->WriteString("quit");
       channel_->Send(msg);
       SetTimer(NULL, 1, 250, (TIMERPROC) PostQuitMessage);
-      return;
+      return true;
     }
 
     IPC::Message* msg = new IPC::Message(0,
@@ -477,6 +480,7 @@ class ChannelPerfListener : public IPC::Channel::Listener {
     msg->WriteInt(count_down_);
     msg->WriteString(payload_);
     channel_->Send(msg);
+    return true;
   }
 
  private:
diff --git a/ipc/sync_socket_unittest.cc b/ipc/sync_socket_unittest.cc
index 451f307620e9aa12d7d81291223d8eef748364df..3598cf320c533b64c236318c91a3f34261a630ab 100644
--- a/ipc/sync_socket_unittest.cc
+++ b/ipc/sync_socket_unittest.cc
@@ -107,13 +107,14 @@ class SyncSocketServerListener : public IPC::Channel::Listener {
     chan_ = chan;
   }
 
-  virtual void OnMessageReceived(const IPC::Message& msg) {
+  virtual bool OnMessageReceived(const IPC::Message& msg) {
     if (msg.routing_id() == MSG_ROUTING_CONTROL) {
       IPC_BEGIN_MESSAGE_MAP(SyncSocketServerListener, msg)
         IPC_MESSAGE_HANDLER(MsgClassSetHandle, OnMsgClassSetHandle)
         IPC_MESSAGE_HANDLER(MsgClassShutdown, OnMsgClassShutdown)
       IPC_END_MESSAGE_MAP()
     }
+    return true;
   }
 
  private:
@@ -175,12 +176,13 @@ class SyncSocketClientListener : public IPC::Channel::Listener {
     chan_ = chan;
   }
 
-  virtual void OnMessageReceived(const IPC::Message& msg) {
+  virtual bool OnMessageReceived(const IPC::Message& msg) {
     if (msg.routing_id() == MSG_ROUTING_CONTROL) {
       IPC_BEGIN_MESSAGE_MAP(SyncSocketClientListener, msg)
         IPC_MESSAGE_HANDLER(MsgClassResponse, OnMsgClassResponse)
       IPC_END_MESSAGE_MAP()
     }
+    return true;
   }
 
  private:
diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc
index 9b7958c4ca0af88f7c03a64f0e7b27d3bbf9edc5..e6637db1db741f7163d946299147bcaf08448e4e 100644
--- a/ppapi/proxy/dispatcher.cc
+++ b/ppapi/proxy/dispatcher.cc
@@ -87,28 +87,32 @@ bool Dispatcher::InitWithChannel(MessageLoop* ipc_message_loop,
   return true;
 }
 
-void Dispatcher::OnMessageReceived(const IPC::Message& msg) {
+bool Dispatcher::OnMessageReceived(const IPC::Message& msg) {
   // Control messages.
   if (msg.routing_id() == MSG_ROUTING_CONTROL) {
+    bool handled = true;
     IPC_BEGIN_MESSAGE_MAP(Dispatcher, msg)
       IPC_MESSAGE_HANDLER(PpapiMsg_DeclareInterfaces,
                           OnMsgDeclareInterfaces)
       IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface)
       IPC_MESSAGE_FORWARD(PpapiMsg_ExecuteCallback, &callback_tracker_,
                           CallbackTracker::ReceiveExecuteSerializedCallback)
+      IPC_MESSAGE_UNHANDLED(handled = false)
     IPC_END_MESSAGE_MAP()
-    return;
+    return handled;
   }
 
   // Interface-specific messages.
   if (msg.routing_id() > 0 && msg.routing_id() < INTERFACE_ID_COUNT) {
     InterfaceProxy* proxy = id_to_proxy_[msg.routing_id()];
     if (proxy)
-      proxy->OnMessageReceived(msg);
-    else
-      NOTREACHED();
+      return proxy->OnMessageReceived(msg);
+
+    NOTREACHED();
     // TODO(brettw): kill the plugin if it starts sending invalid messages?
   }
+
+  return false;
 }
 
 void Dispatcher::SetSerializationRules(
diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h
index 1c76cb8300a52225eec25294cf218f3e81e72569..2aec49cc09aaad8a9e03bbd141ff63267e5467e0 100644
--- a/ppapi/proxy/dispatcher.h
+++ b/ppapi/proxy/dispatcher.h
@@ -103,7 +103,7 @@ class Dispatcher : public IPC::Channel::Listener,
   virtual bool Send(IPC::Message* msg);
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   IPC::SyncChannel* channel() const {
     return channel_.get();
diff --git a/ppapi/proxy/interface_proxy.h b/ppapi/proxy/interface_proxy.h
index 33e19bb87ec9bb2680fea57abb8eae662d1ac15d..672e2682dde1df14618619dc28cf7ee0bc9a428d 100644
--- a/ppapi/proxy/interface_proxy.h
+++ b/ppapi/proxy/interface_proxy.h
@@ -59,7 +59,7 @@ class InterfaceProxy : public IPC::Channel::Listener,
   virtual InterfaceID GetInterfaceId() const = 0;
 
   // Sub-classes must implement IPC::Channel::Listener which contains this:
-  //virtual void OnMessageReceived(const IPC::Message& msg);
+  //virtual bool OnMessageReceived(const IPC::Message& msg);
 
  protected:
   uint32 SendCallback(PP_CompletionCallback callback);
diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc
index a6c97a0512d62d8e97d04e6c30e4205fd3e3f967..ff7ccb787fdb58805f34de33989f98549224e393 100644
--- a/ppapi/proxy/plugin_dispatcher.cc
+++ b/ppapi/proxy/plugin_dispatcher.cc
@@ -70,21 +70,22 @@ bool PluginDispatcher::IsPlugin() const {
   return true;
 }
 
-void PluginDispatcher::OnMessageReceived(const IPC::Message& msg) {
+bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) {
   if (msg.routing_id() == MSG_ROUTING_CONTROL) {
     // Handle some plugin-specific control messages.
+    bool handled = true;
     IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg)
       IPC_MESSAGE_HANDLER(PpapiMsg_InitializeModule, OnMsgInitializeModule)
       IPC_MESSAGE_HANDLER(PpapiMsg_Shutdown, OnMsgShutdown)
 
       // Forward all other control messages to the superclass.
-      IPC_MESSAGE_UNHANDLED(Dispatcher::OnMessageReceived(msg))
+      IPC_MESSAGE_UNHANDLED(handled = Dispatcher::OnMessageReceived(msg))
     IPC_END_MESSAGE_MAP()
-    return;
+    return handled;
   }
 
   // All non-control messages get handled by the superclass.
-  Dispatcher::OnMessageReceived(msg);
+  return Dispatcher::OnMessageReceived(msg);
 }
 
 void PluginDispatcher::OnMsgInitializeModule(PP_Module pp_module,
diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h
index 5b8ffb7b060709bb27c8e64ac8dea8eaa544026c..924b611f10b2d28ae7d43b30ed0f62cc17751ce0 100644
--- a/ppapi/proxy/plugin_dispatcher.h
+++ b/ppapi/proxy/plugin_dispatcher.h
@@ -46,7 +46,7 @@ class PluginDispatcher : public Dispatcher {
   virtual bool IsPlugin() const;
 
   // IPC::Channel::Listener implementation.
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
   // Returns the resource tracker for the plugin. In the browser process this
   // will return NULL.
diff --git a/ppapi/proxy/ppb_audio_config_proxy.cc b/ppapi/proxy/ppb_audio_config_proxy.cc
index 7ec3e8f717afa36a8317ce1984e28284d25f82d7..40abd4f8b9b7da0bf62729fbbd1eddea6861f6c4 100644
--- a/ppapi/proxy/ppb_audio_config_proxy.cc
+++ b/ppapi/proxy/ppb_audio_config_proxy.cc
@@ -107,13 +107,16 @@ InterfaceID PPB_AudioConfig_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_AUDIO_CONFIG;
 }
 
-void PPB_AudioConfig_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_AudioConfig_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_AudioConfig_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudioConfig_Create,
                         OnMsgCreateStereo16Bit)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudioConfig_RecommendSampleFrameCount,
                         OnMsgRecommendSampleFrameCount)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPB_AudioConfig_Proxy::OnMsgCreateStereo16Bit(PP_Module module,
diff --git a/ppapi/proxy/ppb_audio_config_proxy.h b/ppapi/proxy/ppb_audio_config_proxy.h
index b80ea3133522d58d87d564266bc47a747a5b4fb1..0236216b60514fd2d083d8731037dfeabee66e59 100644
--- a/ppapi/proxy/ppb_audio_config_proxy.h
+++ b/ppapi/proxy/ppb_audio_config_proxy.h
@@ -27,7 +27,7 @@ class PPB_AudioConfig_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc
index 84db37a71f313c48ce44a02420e1d91857f1a191..4468c4eeb008d7f0294117b72201245c4c7bf0d5 100644
--- a/ppapi/proxy/ppb_audio_proxy.cc
+++ b/ppapi/proxy/ppb_audio_proxy.cc
@@ -132,15 +132,17 @@ InterfaceID PPB_Audio_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_AUDIO;
 }
 
-void PPB_Audio_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Audio_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Audio_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_Create, OnMsgCreate)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBAudio_StartOrStop,
                         OnMsgStartOrStop)
-
     IPC_MESSAGE_HANDLER(PpapiMsg_PPBAudio_NotifyAudioStreamCreated,
                         OnMsgNotifyAudioStreamCreated)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id,
diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h
index a6d2738cae92f881110137c07d3489c8e55af802..a8dc7487fb3445a98de891ce58709b3e5679c96d 100644
--- a/ppapi/proxy/ppb_audio_proxy.h
+++ b/ppapi/proxy/ppb_audio_proxy.h
@@ -33,7 +33,7 @@ class PPB_Audio_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Plugin->renderer message handlers.
diff --git a/ppapi/proxy/ppb_buffer_proxy.cc b/ppapi/proxy/ppb_buffer_proxy.cc
index 4decffd2cc6b12eafbf53fc17452b39443cf3d3b..0015f5e30b3a05e40c7c47027745ef9b08c636d0 100644
--- a/ppapi/proxy/ppb_buffer_proxy.cc
+++ b/ppapi/proxy/ppb_buffer_proxy.cc
@@ -131,11 +131,14 @@ InterfaceID PPB_Buffer_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_BUFFER;
 }
 
-void PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Buffer_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBuffer_Create, OnMsgCreate)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_Buffer_Proxy::OnMsgCreate(PP_Module module,
diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h
index d2731937daf542f09a382fcfccbb1d4d8cd53707..ccd6721b172568a971e3b910d739b8b688f72c46 100644
--- a/ppapi/proxy/ppb_buffer_proxy.h
+++ b/ppapi/proxy/ppb_buffer_proxy.h
@@ -25,7 +25,7 @@ class PPB_Buffer_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_char_set_proxy.cc b/ppapi/proxy/ppb_char_set_proxy.cc
index d5be4c5b83954ec92dea54b10a9935f040e00eb5..ad650845cbfbedde2e8a23cf3cf08f9599d64961 100644
--- a/ppapi/proxy/ppb_char_set_proxy.cc
+++ b/ppapi/proxy/ppb_char_set_proxy.cc
@@ -88,7 +88,8 @@ InterfaceID PPB_CharSet_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_CHAR_SET;
 }
 
-void PPB_CharSet_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_CharSet_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_CharSet_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCharSet_UTF16ToCharSet,
                         OnMsgUTF16ToCharSet)
@@ -96,7 +97,9 @@ void PPB_CharSet_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgCharSetToUTF16)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCharSet_GetDefaultCharSet,
                         OnMsgGetDefaultCharSet)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPB_CharSet_Proxy::OnMsgUTF16ToCharSet(const string16& utf16,
diff --git a/ppapi/proxy/ppb_char_set_proxy.h b/ppapi/proxy/ppb_char_set_proxy.h
index 17dddd5bc109212330785fbb53ef4787c2c19b0e..d9443731b07902921436673d3c967995bee9433d 100644
--- a/ppapi/proxy/ppb_char_set_proxy.h
+++ b/ppapi/proxy/ppb_char_set_proxy.h
@@ -30,7 +30,7 @@ class PPB_CharSet_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_core_proxy.cc b/ppapi/proxy/ppb_core_proxy.cc
index 51d24d704f81d1d44672b269caab4f3530743d07..32cad6766e8234e35e1bf83e5d2d9df224628e4d 100644
--- a/ppapi/proxy/ppb_core_proxy.cc
+++ b/ppapi/proxy/ppb_core_proxy.cc
@@ -96,14 +96,17 @@ InterfaceID PPB_Core_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_CORE;
 }
 
-void PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Core_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_AddRefResource,
                         OnMsgAddRefResource)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCore_ReleaseResource,
                         OnMsgReleaseResource)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_Core_Proxy::OnMsgAddRefResource(PP_Resource resource) {
diff --git a/ppapi/proxy/ppb_core_proxy.h b/ppapi/proxy/ppb_core_proxy.h
index 66f17d8adb44b52bf7697c323e4f2ac0ad3adb24..ece12dc7577c696ac3161646661793dc0640be84 100644
--- a/ppapi/proxy/ppb_core_proxy.h
+++ b/ppapi/proxy/ppb_core_proxy.h
@@ -27,7 +27,7 @@ class PPB_Core_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_cursor_control_proxy.cc b/ppapi/proxy/ppb_cursor_control_proxy.cc
index 4c6eaaea5d1b663628186ec158537cb83206832d..f576ae022de244f3ac2eaf0803fe3d0e9c466152 100644
--- a/ppapi/proxy/ppb_cursor_control_proxy.cc
+++ b/ppapi/proxy/ppb_cursor_control_proxy.cc
@@ -80,7 +80,8 @@ InterfaceID PPB_CursorControl_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_CURSORCONTROL;
 }
 
-void PPB_CursorControl_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_CursorControl_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_CursorControl_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCursorControl_SetCursor,
                         OnMsgSetCursor)
@@ -92,8 +93,10 @@ void PPB_CursorControl_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgHasCursorLock)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBCursorControl_CanLockCursor,
                         OnMsgCanLockCursor)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw): handle bad messages!
+  return handled;
 }
 
 void PPB_CursorControl_Proxy::OnMsgSetCursor(PP_Instance instance,
diff --git a/ppapi/proxy/ppb_cursor_control_proxy.h b/ppapi/proxy/ppb_cursor_control_proxy.h
index f540c0a4d870b6aa458da2ef1c1929041c8e4e5e..033e6c10d476601f9d6efaf89dabb9528bbcb558 100644
--- a/ppapi/proxy/ppb_cursor_control_proxy.h
+++ b/ppapi/proxy/ppb_cursor_control_proxy.h
@@ -29,7 +29,7 @@ class PPB_CursorControl_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc
index 5614e6a4656c6661eedd282073455b45559a56b9..13fe1d09fbf3cfd3d4398d19dfea8ccbfd23106e 100644
--- a/ppapi/proxy/ppb_flash_proxy.cc
+++ b/ppapi/proxy/ppb_flash_proxy.cc
@@ -224,7 +224,8 @@ InterfaceID PPB_Flash_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_FLASH;
 }
 
-void PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Flash_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop,
                         OnMsgSetInstanceAlwaysOnTop)
@@ -245,8 +246,10 @@ void PPB_Flash_Proxy::OnMessageReceived(const IPC::Message& msg) {
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetModuleLocalDirContents,
                         OnMsgGetModuleLocalDirContents)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_NavigateToURL, OnMsgNavigateToURL)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_Flash_Proxy::OnMsgSetInstanceAlwaysOnTop(
diff --git a/ppapi/proxy/ppb_flash_proxy.h b/ppapi/proxy/ppb_flash_proxy.h
index 8961a47c8105971c17b97c1b8c7acd34a69b487f..629761fabb4024cb22bfe8fca5ff7528bb0b0c26 100644
--- a/ppapi/proxy/ppb_flash_proxy.h
+++ b/ppapi/proxy/ppb_flash_proxy.h
@@ -35,7 +35,7 @@ class PPB_Flash_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_font_proxy.cc b/ppapi/proxy/ppb_font_proxy.cc
index 9a4dbf5670fc54954ad12792d3b7f501d7021527..1c72622c14448f66b622cd933f200f0adb3bfd23 100644
--- a/ppapi/proxy/ppb_font_proxy.cc
+++ b/ppapi/proxy/ppb_font_proxy.cc
@@ -187,7 +187,8 @@ InterfaceID PPB_Font_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_FONT;
 }
 
-void PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Font_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_Create,
                         OnMsgCreate)
@@ -199,7 +200,9 @@ void PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgCharacterOffsetForPixel)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFont_PixelOffsetForCharacter,
                         OnMsgPixelOffsetForCharacter)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPB_Font_Proxy::OnMsgCreate(
diff --git a/ppapi/proxy/ppb_font_proxy.h b/ppapi/proxy/ppb_font_proxy.h
index 25e14ed77edfc9ae01deb5e7af6012c17365311f..4e68d70f6a9da847c235a357a846135755753e15 100644
--- a/ppapi/proxy/ppb_font_proxy.h
+++ b/ppapi/proxy/ppb_font_proxy.h
@@ -31,7 +31,7 @@ class PPB_Font_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_fullscreen_proxy.cc b/ppapi/proxy/ppb_fullscreen_proxy.cc
index ddf0cdbf723ad966d879cb169b0fdea91a8f2ba1..ab537ea47079081336681123140424ec0aeda4a0 100644
--- a/ppapi/proxy/ppb_fullscreen_proxy.cc
+++ b/ppapi/proxy/ppb_fullscreen_proxy.cc
@@ -50,14 +50,17 @@ InterfaceID PPB_Fullscreen_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_FULLSCREEN;
 }
 
-void PPB_Fullscreen_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Fullscreen_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Fullscreen_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFullscreen_IsFullscreen,
                         OnMsgIsFullscreen)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFullscreen_SetFullscreen,
                         OnMsgSetFullscreen)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw): handle bad messages!
+  return handled;
 }
 
 void PPB_Fullscreen_Proxy::OnMsgIsFullscreen(PP_Instance instance,
diff --git a/ppapi/proxy/ppb_fullscreen_proxy.h b/ppapi/proxy/ppb_fullscreen_proxy.h
index f24eb7eb1608bda167a62b3a9e3bf959c1d284c8..502d5b1c9394295e6082a2b26c288ca0c8c0333f 100644
--- a/ppapi/proxy/ppb_fullscreen_proxy.h
+++ b/ppapi/proxy/ppb_fullscreen_proxy.h
@@ -27,7 +27,7 @@ class PPB_Fullscreen_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc
index 74f8b91c3f07c52202772d7364c6058fc18e3816..06d5d0a6a3573e7d70d82c7e364387a7c35b1a6a 100644
--- a/ppapi/proxy/ppb_graphics_2d_proxy.cc
+++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc
@@ -166,7 +166,8 @@ InterfaceID PPB_Graphics2D_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_GRAPHICS_2D;
 }
 
-void PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Graphics2D_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics2D_Create,
                         OnMsgCreate)
@@ -181,8 +182,10 @@ void PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) {
 
     IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics2D_FlushACK,
                         OnMsgFlushACK)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // FIXME(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_Graphics2D_Proxy::OnMsgCreate(PP_Module module,
diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.h b/ppapi/proxy/ppb_graphics_2d_proxy.h
index 66226b91c63c2e95b4bad2cd9d5f17e460614636..96d3277c1d7d807faa2e39f5683576933b5d513d 100644
--- a/ppapi/proxy/ppb_graphics_2d_proxy.h
+++ b/ppapi/proxy/ppb_graphics_2d_proxy.h
@@ -35,7 +35,7 @@ class PPB_Graphics2D_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Plugin->renderer message handlers.
diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc
index 4fa4205ed415ece10b68e044885064945109c486..14b047993b7f0ba41793a354d977500dbdef72da 100644
--- a/ppapi/proxy/ppb_image_data_proxy.cc
+++ b/ppapi/proxy/ppb_image_data_proxy.cc
@@ -119,15 +119,18 @@ InterfaceID PPB_ImageData_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_IMAGE_DATA;
 }
 
-void PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_ImageData_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_ImageData_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_GetNativeImageDataFormat,
                         OnMsgGetNativeImageDataFormat)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_IsImageDataFormatSupported,
                         OnMsgIsImageDataFormatSupported)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBImageData_Create, OnMsgCreate)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // FIXME(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_ImageData_Proxy::OnMsgGetNativeImageDataFormat(int32* result) {
diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h
index 5ff617ca529f34a7e0648365aaebb2af607abbb2..beec054aafed7acd6d1c9916bd32245871e2e080 100644
--- a/ppapi/proxy/ppb_image_data_proxy.h
+++ b/ppapi/proxy/ppb_image_data_proxy.h
@@ -32,7 +32,7 @@ class PPB_ImageData_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc
index 1703b749db4b2a06930cad8c9deec326ebcd95ca..b26a0284c68f27bb074acf9569d89b30c181d095 100644
--- a/ppapi/proxy/ppb_instance_proxy.cc
+++ b/ppapi/proxy/ppb_instance_proxy.cc
@@ -84,7 +84,8 @@ InterfaceID PPB_Instance_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_INSTANCE;
 }
 
-void PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Instance_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetWindowObject,
                         OnMsgGetWindowObject)
@@ -96,7 +97,9 @@ void PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgIsFullFrame)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ExecuteScript,
                         OnMsgExecuteScript)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPB_Instance_Proxy::OnMsgGetWindowObject(
diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h
index 578f38b8a079d880b8a04f8f68f4c2486b1468fe..b01e9b079c2f3bf36e985de24652765a0c87fe48 100644
--- a/ppapi/proxy/ppb_instance_proxy.h
+++ b/ppapi/proxy/ppb_instance_proxy.h
@@ -31,7 +31,7 @@ class PPB_Instance_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_pdf_proxy.cc b/ppapi/proxy/ppb_pdf_proxy.cc
index 0ba638ed44ef5a41fb6da0954f1fada735d7104b..cbd1f319479844af9ace41c69d71a1692f746e3c 100644
--- a/ppapi/proxy/ppb_pdf_proxy.cc
+++ b/ppapi/proxy/ppb_pdf_proxy.cc
@@ -125,14 +125,17 @@ InterfaceID PPB_PDF_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_PDF;
 }
 
-void PPB_PDF_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_PDF_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_PDF_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBPDF_GetFontFileWithFallback,
                         OnMsgGetFontFileWithFallback)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBPDF_GetFontTableForPrivateFontFile,
                         OnMsgGetFontTableForPrivateFontFile)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw): handle bad messages!
+  return handled;
 }
 
 void PPB_PDF_Proxy::OnMsgGetFontFileWithFallback(
diff --git a/ppapi/proxy/ppb_pdf_proxy.h b/ppapi/proxy/ppb_pdf_proxy.h
index f229df214aae0f13c839fbd9378b10c57359ac91..071a493514fab18f49af6de498579fe499965cf1 100644
--- a/ppapi/proxy/ppb_pdf_proxy.h
+++ b/ppapi/proxy/ppb_pdf_proxy.h
@@ -27,7 +27,7 @@ class PPB_PDF_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc
index d4ab8cc2e7cd3b9ada3d1c5dd84eb6242c0a8396..946cecb0ffcd441abc628a7edd22e2e1ce9dd59b 100644
--- a/ppapi/proxy/ppb_testing_proxy.cc
+++ b/ppapi/proxy/ppb_testing_proxy.cc
@@ -66,7 +66,8 @@ InterfaceID PPB_Testing_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_TESTING;
 }
 
-void PPB_Testing_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Testing_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Testing_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_ReadImageData,
                         OnMsgReadImageData)
@@ -76,7 +77,9 @@ void PPB_Testing_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgQuitMessageLoop)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTesting_GetLiveObjectCount,
                         OnMsgGetLiveObjectCount)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPB_Testing_Proxy::OnMsgReadImageData(PP_Resource device_context_2d,
diff --git a/ppapi/proxy/ppb_testing_proxy.h b/ppapi/proxy/ppb_testing_proxy.h
index 547f8abf8ccb1d3f722eb25d697a4245955a03ae..23314a849299632e14d0e384f71e91f484fcdc47 100644
--- a/ppapi/proxy/ppb_testing_proxy.h
+++ b/ppapi/proxy/ppb_testing_proxy.h
@@ -28,7 +28,7 @@ class PPB_Testing_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc
index 0d5bbb29b41d0b3fc78a399087954a6e70c21b1e..e60afd1c8d1503069c7e160dc13bb6c96ba2a751 100644
--- a/ppapi/proxy/ppb_url_loader_proxy.cc
+++ b/ppapi/proxy/ppb_url_loader_proxy.cc
@@ -248,7 +248,8 @@ InterfaceID PPB_URLLoader_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_URL_LOADER;
 }
 
-void PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_URLLoader_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoader_Create,
                         OnMsgCreate)
@@ -269,8 +270,10 @@ void PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgUpdateProgress)
     IPC_MESSAGE_HANDLER(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack,
                         OnMsgReadResponseBodyAck)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance,
@@ -427,12 +430,15 @@ InterfaceID PPB_URLLoaderTrusted_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_URL_LOADER_TRUSTED;
 }
 
-void PPB_URLLoaderTrusted_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_URLLoaderTrusted_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_URLLoaderTrusted_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess,
                         OnMsgGrantUniversalAccess)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP();
   // TODO(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_URLLoaderTrusted_Proxy::OnMsgGrantUniversalAccess(PP_Resource loader) {
diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h
index ca9a83d8d988848628304dbc705840ca4767ed9c..3755d460b89bc36ab2cb68a4bfe2b1206492c5ef 100644
--- a/ppapi/proxy/ppb_url_loader_proxy.h
+++ b/ppapi/proxy/ppb_url_loader_proxy.h
@@ -39,7 +39,7 @@ class PPB_URLLoader_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Data associated with callbacks for ReadResponseBody.
@@ -92,7 +92,7 @@ class PPB_URLLoaderTrusted_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Plugin->renderer message handlers.
diff --git a/ppapi/proxy/ppb_url_request_info_proxy.cc b/ppapi/proxy/ppb_url_request_info_proxy.cc
index 6a91286554547280830182af680ade2f725bae5b..02bd3e6233b6b6374e9cda6b26a0f5542b5b00c9 100644
--- a/ppapi/proxy/ppb_url_request_info_proxy.cc
+++ b/ppapi/proxy/ppb_url_request_info_proxy.cc
@@ -111,7 +111,8 @@ InterfaceID PPB_URLRequestInfo_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_URL_REQUEST_INFO;
 }
 
-void PPB_URLRequestInfo_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_URLRequestInfo_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_URLRequestInfo_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_Create, OnMsgCreate)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_SetProperty,
@@ -120,8 +121,10 @@ void PPB_URLRequestInfo_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgAppendDataToBody)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody,
                         OnMsgAppendFileToBody)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw): handle bad messages.
+  return handled;
 }
 
 void PPB_URLRequestInfo_Proxy::OnMsgCreate(
diff --git a/ppapi/proxy/ppb_url_request_info_proxy.h b/ppapi/proxy/ppb_url_request_info_proxy.h
index b620f4ab59f1193db09f83e0eccbfb1eddf2201a..47e2e277e5a722921d0ec52b37a0444c2983627a 100644
--- a/ppapi/proxy/ppb_url_request_info_proxy.h
+++ b/ppapi/proxy/ppb_url_request_info_proxy.h
@@ -30,7 +30,7 @@ class PPB_URLRequestInfo_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_url_response_info_proxy.cc b/ppapi/proxy/ppb_url_response_info_proxy.cc
index c85150e5e2a2bfedf96d77f7ee64139948467c73..01e1763d17c7f661ab7e1fd6f2ae70a9f2a84c00 100644
--- a/ppapi/proxy/ppb_url_response_info_proxy.cc
+++ b/ppapi/proxy/ppb_url_response_info_proxy.cc
@@ -85,14 +85,17 @@ InterfaceID PPB_URLResponseInfo_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_URL_RESPONSE_INFO;
 }
 
-void PPB_URLResponseInfo_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_URLResponseInfo_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_URLResponseInfo_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLResponseInfo_GetProperty,
                         OnMsgGetProperty)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef,
                         OnMsgGetBodyAsFileRef)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw): handle bad messages.
+  return handled;
 }
 
 void PPB_URLResponseInfo_Proxy::OnMsgGetProperty(
diff --git a/ppapi/proxy/ppb_url_response_info_proxy.h b/ppapi/proxy/ppb_url_response_info_proxy.h
index 423ca3eff800a2a9da8ec95f80e12fe97070e71d..c1de2594a23ebe072ef8b5b05c5e14f27b113dc7 100644
--- a/ppapi/proxy/ppb_url_response_info_proxy.h
+++ b/ppapi/proxy/ppb_url_response_info_proxy.h
@@ -35,7 +35,7 @@ class PPB_URLResponseInfo_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc
index 42abbc77fcd208c39c05e7f7eb5d17298e213eca..f37b0e3e9d960b4353ee8c97b3996e270b01aa71 100644
--- a/ppapi/proxy/ppb_var_deprecated_proxy.cc
+++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc
@@ -247,7 +247,8 @@ InterfaceID PPB_Var_Deprecated_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPB_VAR_DEPRECATED;
 }
 
-void PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPB_Var_Deprecated_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasProperty,
                         OnMsgHasProperty)
@@ -269,8 +270,10 @@ void PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgIsInstanceOfDeprecated)
     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CreateObjectDeprecated,
                         OnMsgCreateObjectDeprecated)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   // TODO(brettw) handle bad messages!
+  return handled;
 }
 
 void PPB_Var_Deprecated_Proxy::OnMsgHasProperty(
diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.h b/ppapi/proxy/ppb_var_deprecated_proxy.h
index 414844711a583cd8f694a1fecedd510041032c3d..c712460d5e9412faf229396822e22913520f1fa4 100644
--- a/ppapi/proxy/ppb_var_deprecated_proxy.h
+++ b/ppapi/proxy/ppb_var_deprecated_proxy.h
@@ -37,7 +37,7 @@ class PPB_Var_Deprecated_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.
diff --git a/ppapi/proxy/ppp_class_proxy.cc b/ppapi/proxy/ppp_class_proxy.cc
index b2fad17cb85bda60933a3149fbbb49fe5472dacf..ab71565fc5b3cfd7dbe4aa4c83e3c5185836d3c7 100644
--- a/ppapi/proxy/ppp_class_proxy.cc
+++ b/ppapi/proxy/ppp_class_proxy.cc
@@ -200,7 +200,8 @@ InterfaceID PPP_Class_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPP_CLASS;
 }
 
-void PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPP_Class_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_HasProperty,
                         OnMsgHasProperty)
@@ -218,7 +219,9 @@ void PPP_Class_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgConstruct)
     IPC_MESSAGE_HANDLER(PpapiMsg_PPPClass_Deallocate,
                         OnMsgDeallocate)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPP_Class_Proxy::OnMsgHasProperty(int64 ppp_class, int64 object,
diff --git a/ppapi/proxy/ppp_class_proxy.h b/ppapi/proxy/ppp_class_proxy.h
index b22d86a04d5ae4a85bdf693d52dc6c9fd813eead..d4e2102b3e1931402d23b1b28a27054281a6806f 100644
--- a/ppapi/proxy/ppp_class_proxy.h
+++ b/ppapi/proxy/ppp_class_proxy.h
@@ -42,7 +42,7 @@ class PPP_Class_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // IPC message handlers.
diff --git a/ppapi/proxy/ppp_instance_proxy.cc b/ppapi/proxy/ppp_instance_proxy.cc
index 8551d2be9fca56b325d582546fee3cd73475ae2f..886b7f191fabf44defeba84387a13159ccb45c63 100644
--- a/ppapi/proxy/ppp_instance_proxy.cc
+++ b/ppapi/proxy/ppp_instance_proxy.cc
@@ -109,7 +109,8 @@ InterfaceID PPP_Instance_Proxy::GetInterfaceId() const {
   return INTERFACE_ID_PPP_INSTANCE;
 }
 
-void PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+bool PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
+  bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(PPP_Instance_Proxy, msg)
     IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_DidCreate,
                         OnMsgDidCreate)
@@ -125,7 +126,9 @@ void PPP_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) {
                         OnMsgHandleDocumentLoad)
     IPC_MESSAGE_HANDLER(PpapiMsg_PPPInstance_GetInstanceObject,
                         OnMsgGetInstanceObject)
+    IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
+  return handled;
 }
 
 void PPP_Instance_Proxy::OnMsgDidCreate(
diff --git a/ppapi/proxy/ppp_instance_proxy.h b/ppapi/proxy/ppp_instance_proxy.h
index 9df247bf2ee5c65d714e807b7edfe2a085f34f79..5d02fc80ff262a7ad4cb6840af6a4b7b2bdf18fe 100644
--- a/ppapi/proxy/ppp_instance_proxy.h
+++ b/ppapi/proxy/ppp_instance_proxy.h
@@ -34,7 +34,7 @@ class PPP_Instance_Proxy : public InterfaceProxy {
   // InterfaceProxy implementation.
   virtual const void* GetSourceInterface() const;
   virtual InterfaceID GetInterfaceId() const;
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual bool OnMessageReceived(const IPC::Message& msg);
 
  private:
   // Message handlers.