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.
5 #include "extensions/browser/extension_message_filter.h"
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.h"
17 #include "extensions/common/extension_messages.h"
18 #include "ipc/ipc_message_macros.h"
20 using content::BrowserThread;
21 using content::RenderProcessHost;
23 namespace extensions {
25 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id,
26 content::BrowserContext* context)
27 : BrowserMessageFilter(ExtensionMsgStart),
28 render_process_id_(render_process_id),
29 browser_context_(context),
30 extension_info_map_(ExtensionSystem::Get(context)->info_map()),
31 weak_ptr_factory_(this) {
32 DCHECK_CURRENTLY_ON(BrowserThread::UI);
35 ExtensionMessageFilter::~ExtensionMessageFilter() {
36 DCHECK_CURRENTLY_ON(BrowserThread::IO);
39 void ExtensionMessageFilter::OverrideThreadForMessage(
40 const IPC::Message& message,
41 BrowserThread::ID* thread) {
42 switch (message.type()) {
43 case ExtensionHostMsg_AddListener::ID:
44 case ExtensionHostMsg_RemoveListener::ID:
45 case ExtensionHostMsg_AddLazyListener::ID:
46 case ExtensionHostMsg_RemoveLazyListener::ID:
47 case ExtensionHostMsg_AddFilteredListener::ID:
48 case ExtensionHostMsg_RemoveFilteredListener::ID:
49 case ExtensionHostMsg_ShouldSuspendAck::ID:
50 case ExtensionHostMsg_SuspendAck::ID:
51 case ExtensionHostMsg_TransferBlobsAck::ID:
52 *thread = BrowserThread::UI;
59 void ExtensionMessageFilter::OnDestruct() const {
60 // Destroy the filter on the IO thread since that's where its weak pointers
62 BrowserThread::DeleteOnIOThread::Destruct(this);
65 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) {
67 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message)
68 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener,
69 OnExtensionAddListener)
70 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener,
71 OnExtensionRemoveListener)
72 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener,
73 OnExtensionAddLazyListener)
74 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener,
75 OnExtensionRemoveLazyListener)
76 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener,
77 OnExtensionAddFilteredListener)
78 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener,
79 OnExtensionRemoveFilteredListener)
80 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck,
81 OnExtensionShouldSuspendAck)
82 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck,
83 OnExtensionSuspendAck)
84 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck,
85 OnExtensionTransferBlobsAck)
86 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID,
87 OnExtensionGenerateUniqueID)
88 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests,
89 OnExtensionResumeRequests);
90 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread,
91 OnExtensionRequestForIOThread)
92 IPC_MESSAGE_UNHANDLED(handled = false)
97 void ExtensionMessageFilter::OnExtensionAddListener(
98 const std::string& extension_id,
99 const GURL& listener_url,
100 const std::string& event_name) {
101 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
104 EventRouter* router = EventRouter::Get(browser_context_);
108 if (Extension::IdIsValid(extension_id)) {
109 router->AddEventListener(event_name, process, extension_id);
110 } else if (listener_url.is_valid()) {
111 router->AddEventListenerForURL(event_name, process, listener_url);
113 NOTREACHED() << "Tried to add an event listener without a valid "
114 << "extension ID nor listener URL";
118 void ExtensionMessageFilter::OnExtensionRemoveListener(
119 const std::string& extension_id,
120 const GURL& listener_url,
121 const std::string& event_name) {
122 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
125 EventRouter* router = EventRouter::Get(browser_context_);
129 if (Extension::IdIsValid(extension_id)) {
130 router->RemoveEventListener(event_name, process, extension_id);
131 } else if (listener_url.is_valid()) {
132 router->RemoveEventListenerForURL(event_name, process, listener_url);
134 NOTREACHED() << "Tried to remove an event listener without a valid "
135 << "extension ID nor listener URL";
139 void ExtensionMessageFilter::OnExtensionAddLazyListener(
140 const std::string& extension_id, const std::string& event_name) {
141 EventRouter* router = EventRouter::Get(browser_context_);
144 router->AddLazyEventListener(event_name, extension_id);
147 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
148 const std::string& extension_id, const std::string& event_name) {
149 EventRouter* router = EventRouter::Get(browser_context_);
152 router->RemoveLazyEventListener(event_name, extension_id);
155 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
156 const std::string& extension_id,
157 const std::string& event_name,
158 const base::DictionaryValue& filter,
160 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
163 EventRouter* router = EventRouter::Get(browser_context_);
166 router->AddFilteredEventListener(
167 event_name, process, extension_id, filter, lazy);
170 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
171 const std::string& extension_id,
172 const std::string& event_name,
173 const base::DictionaryValue& filter,
175 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
178 EventRouter* router = EventRouter::Get(browser_context_);
181 router->RemoveFilteredEventListener(
182 event_name, process, extension_id, filter, lazy);
185 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
186 const std::string& extension_id, int sequence_id) {
187 ProcessManager* process_manager =
188 ExtensionSystem::Get(browser_context_)->process_manager();
190 process_manager->OnShouldSuspendAck(extension_id, sequence_id);
193 void ExtensionMessageFilter::OnExtensionSuspendAck(
194 const std::string& extension_id) {
195 ProcessManager* process_manager =
196 ExtensionSystem::Get(browser_context_)->process_manager();
198 process_manager->OnSuspendAck(extension_id);
201 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
202 const std::vector<std::string>& blob_uuids) {
203 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
206 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids);
209 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) {
210 static int next_unique_id = 0;
211 *unique_id = ++next_unique_id;
214 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id) {
215 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
216 render_process_id_, route_id);
219 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
221 const ExtensionHostMsg_Request_Params& params) {
222 DCHECK_CURRENTLY_ON(BrowserThread::IO);
223 ExtensionFunctionDispatcher::DispatchOnIOThread(
224 extension_info_map_.get(),
227 weak_ptr_factory_.GetWeakPtr(),
232 } // namespace extensions