1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "extensions/browser/extension_message_filter.h" 6 7 #include "content/public/browser/browser_thread.h" 8 #include "content/public/browser/render_process_host.h" 9 #include "content/public/browser/resource_dispatcher_host.h" 10 #include "extensions/browser/blob_holder.h" 11 #include "extensions/browser/event_router.h" 12 #include "extensions/browser/extension_function_dispatcher.h" 13 #include "extensions/browser/extension_system.h" 14 #include "extensions/browser/info_map.h" 15 #include "extensions/browser/process_manager.h" 16 #include "extensions/common/extension_messages.h" 17 #include "ipc/ipc_message_macros.h" 18 19 using content::BrowserThread; 20 using content::RenderProcessHost; 21 22 namespace extensions { 23 24 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id, 25 content::BrowserContext* context) 26 : BrowserMessageFilter(ExtensionMsgStart), 27 render_process_id_(render_process_id), 28 browser_context_(context), 29 extension_info_map_(ExtensionSystem::Get(context)->info_map()), 30 weak_ptr_factory_(this) { 31 DCHECK_CURRENTLY_ON(BrowserThread::UI); 32 } 33 34 ExtensionMessageFilter::~ExtensionMessageFilter() { 35 DCHECK_CURRENTLY_ON(BrowserThread::IO); 36 } 37 38 void ExtensionMessageFilter::OverrideThreadForMessage( 39 const IPC::Message& message, 40 BrowserThread::ID* thread) { 41 switch (message.type()) { 42 case ExtensionHostMsg_AddListener::ID: 43 case ExtensionHostMsg_RemoveListener::ID: 44 case ExtensionHostMsg_AddLazyListener::ID: 45 case ExtensionHostMsg_RemoveLazyListener::ID: 46 case ExtensionHostMsg_AddFilteredListener::ID: 47 case ExtensionHostMsg_RemoveFilteredListener::ID: 48 case ExtensionHostMsg_ShouldSuspendAck::ID: 49 case ExtensionHostMsg_SuspendAck::ID: 50 case ExtensionHostMsg_TransferBlobsAck::ID: 51 *thread = BrowserThread::UI; 52 break; 53 default: 54 break; 55 } 56 } 57 58 void ExtensionMessageFilter::OnDestruct() const { 59 // Destroy the filter on the IO thread since that's where its weak pointers 60 // are being used. 61 BrowserThread::DeleteOnIOThread::Destruct(this); 62 } 63 64 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) { 65 bool handled = true; 66 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message) 67 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, 68 OnExtensionAddListener) 69 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener, 70 OnExtensionRemoveListener) 71 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener, 72 OnExtensionAddLazyListener) 73 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, 74 OnExtensionRemoveLazyListener) 75 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, 76 OnExtensionAddFilteredListener) 77 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, 78 OnExtensionRemoveFilteredListener) 79 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck, 80 OnExtensionShouldSuspendAck) 81 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, 82 OnExtensionSuspendAck) 83 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck, 84 OnExtensionTransferBlobsAck) 85 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID, 86 OnExtensionGenerateUniqueID) 87 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests, 88 OnExtensionResumeRequests); 89 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread, 90 OnExtensionRequestForIOThread) 91 IPC_MESSAGE_UNHANDLED(handled = false) 92 IPC_END_MESSAGE_MAP() 93 return handled; 94 } 95 96 void ExtensionMessageFilter::OnExtensionAddListener( 97 const std::string& extension_id, 98 const std::string& event_name) { 99 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); 100 if (!process) 101 return; 102 EventRouter* router = EventRouter::Get(browser_context_); 103 if (!router) 104 return; 105 router->AddEventListener(event_name, process, extension_id); 106 } 107 108 void ExtensionMessageFilter::OnExtensionRemoveListener( 109 const std::string& extension_id, 110 const std::string& event_name) { 111 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); 112 if (!process) 113 return; 114 EventRouter* router = EventRouter::Get(browser_context_); 115 if (!router) 116 return; 117 router->RemoveEventListener(event_name, process, extension_id); 118 } 119 120 void ExtensionMessageFilter::OnExtensionAddLazyListener( 121 const std::string& extension_id, const std::string& event_name) { 122 EventRouter* router = EventRouter::Get(browser_context_); 123 if (!router) 124 return; 125 router->AddLazyEventListener(event_name, extension_id); 126 } 127 128 void ExtensionMessageFilter::OnExtensionRemoveLazyListener( 129 const std::string& extension_id, const std::string& event_name) { 130 EventRouter* router = EventRouter::Get(browser_context_); 131 if (!router) 132 return; 133 router->RemoveLazyEventListener(event_name, extension_id); 134 } 135 136 void ExtensionMessageFilter::OnExtensionAddFilteredListener( 137 const std::string& extension_id, 138 const std::string& event_name, 139 const base::DictionaryValue& filter, 140 bool lazy) { 141 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); 142 if (!process) 143 return; 144 EventRouter* router = EventRouter::Get(browser_context_); 145 if (!router) 146 return; 147 router->AddFilteredEventListener( 148 event_name, process, extension_id, filter, lazy); 149 } 150 151 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener( 152 const std::string& extension_id, 153 const std::string& event_name, 154 const base::DictionaryValue& filter, 155 bool lazy) { 156 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); 157 if (!process) 158 return; 159 EventRouter* router = EventRouter::Get(browser_context_); 160 if (!router) 161 return; 162 router->RemoveFilteredEventListener( 163 event_name, process, extension_id, filter, lazy); 164 } 165 166 void ExtensionMessageFilter::OnExtensionShouldSuspendAck( 167 const std::string& extension_id, int sequence_id) { 168 ProcessManager* process_manager = 169 ExtensionSystem::Get(browser_context_)->process_manager(); 170 if (process_manager) 171 process_manager->OnShouldSuspendAck(extension_id, sequence_id); 172 } 173 174 void ExtensionMessageFilter::OnExtensionSuspendAck( 175 const std::string& extension_id) { 176 ProcessManager* process_manager = 177 ExtensionSystem::Get(browser_context_)->process_manager(); 178 if (process_manager) 179 process_manager->OnSuspendAck(extension_id); 180 } 181 182 void ExtensionMessageFilter::OnExtensionTransferBlobsAck( 183 const std::vector<std::string>& blob_uuids) { 184 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); 185 if (!process) 186 return; 187 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids); 188 } 189 190 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) { 191 static int next_unique_id = 0; 192 *unique_id = ++next_unique_id; 193 } 194 195 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id) { 196 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute( 197 render_process_id_, route_id); 198 } 199 200 void ExtensionMessageFilter::OnExtensionRequestForIOThread( 201 int routing_id, 202 const ExtensionHostMsg_Request_Params& params) { 203 DCHECK_CURRENTLY_ON(BrowserThread::IO); 204 ExtensionFunctionDispatcher::DispatchOnIOThread( 205 extension_info_map_.get(), 206 browser_context_, 207 render_process_id_, 208 weak_ptr_factory_.GetWeakPtr(), 209 routing_id, 210 params); 211 } 212 213 } // namespace extensions 214