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 "components/crx_file/id_util.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/resource_dispatcher_host.h"
11 #include "extensions/browser/blob_holder.h"
12 #include "extensions/browser/event_router.h"
13 #include "extensions/browser/extension_function_dispatcher.h"
14 #include "extensions/browser/extension_system.h"
15 #include "extensions/browser/guest_view/guest_view_manager.h"
16 #include "extensions/browser/info_map.h"
17 #include "extensions/browser/process_manager.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/extension_messages.h"
20 #include "ipc/ipc_message_macros.h"
22 using content::BrowserThread
;
23 using content::RenderProcessHost
;
25 namespace extensions
{
27 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id
,
28 content::BrowserContext
* context
)
29 : BrowserMessageFilter(ExtensionMsgStart
),
30 render_process_id_(render_process_id
),
31 browser_context_(context
),
32 extension_info_map_(ExtensionSystem::Get(context
)->info_map()),
33 weak_ptr_factory_(this) {
34 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
37 ExtensionMessageFilter::~ExtensionMessageFilter() {
38 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
41 void ExtensionMessageFilter::OverrideThreadForMessage(
42 const IPC::Message
& message
,
43 BrowserThread::ID
* thread
) {
44 switch (message
.type()) {
45 case ExtensionHostMsg_AddListener::ID
:
46 case ExtensionHostMsg_AttachGuest::ID
:
47 case ExtensionHostMsg_RemoveListener::ID
:
48 case ExtensionHostMsg_AddLazyListener::ID
:
49 case ExtensionHostMsg_RemoveLazyListener::ID
:
50 case ExtensionHostMsg_AddFilteredListener::ID
:
51 case ExtensionHostMsg_RemoveFilteredListener::ID
:
52 case ExtensionHostMsg_ShouldSuspendAck::ID
:
53 case ExtensionHostMsg_SuspendAck::ID
:
54 case ExtensionHostMsg_TransferBlobsAck::ID
:
55 *thread
= BrowserThread::UI
;
62 void ExtensionMessageFilter::OnDestruct() const {
63 // Destroy the filter on the IO thread since that's where its weak pointers
65 BrowserThread::DeleteOnIOThread::Destruct(this);
68 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message
& message
) {
70 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter
, message
)
71 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener
,
72 OnExtensionAddListener
)
73 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener
,
74 OnExtensionRemoveListener
)
75 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener
,
76 OnExtensionAddLazyListener
)
77 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AttachGuest
,
78 OnExtensionAttachGuest
)
79 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener
,
80 OnExtensionRemoveLazyListener
)
81 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener
,
82 OnExtensionAddFilteredListener
)
83 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener
,
84 OnExtensionRemoveFilteredListener
)
85 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck
,
86 OnExtensionShouldSuspendAck
)
87 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck
,
88 OnExtensionSuspendAck
)
89 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck
,
90 OnExtensionTransferBlobsAck
)
91 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID
,
92 OnExtensionGenerateUniqueID
)
93 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests
,
94 OnExtensionResumeRequests
);
95 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread
,
96 OnExtensionRequestForIOThread
)
97 IPC_MESSAGE_UNHANDLED(handled
= false)
102 void ExtensionMessageFilter::OnExtensionAddListener(
103 const std::string
& extension_id
,
104 const GURL
& listener_url
,
105 const std::string
& event_name
) {
106 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
109 EventRouter
* router
= EventRouter::Get(browser_context_
);
113 if (crx_file::id_util::IdIsValid(extension_id
)) {
114 router
->AddEventListener(event_name
, process
, extension_id
);
115 } else if (listener_url
.is_valid()) {
116 router
->AddEventListenerForURL(event_name
, process
, listener_url
);
118 NOTREACHED() << "Tried to add an event listener without a valid "
119 << "extension ID nor listener URL";
123 void ExtensionMessageFilter::OnExtensionRemoveListener(
124 const std::string
& extension_id
,
125 const GURL
& listener_url
,
126 const std::string
& event_name
) {
127 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
130 EventRouter
* router
= EventRouter::Get(browser_context_
);
134 if (crx_file::id_util::IdIsValid(extension_id
)) {
135 router
->RemoveEventListener(event_name
, process
, extension_id
);
136 } else if (listener_url
.is_valid()) {
137 router
->RemoveEventListenerForURL(event_name
, process
, listener_url
);
139 NOTREACHED() << "Tried to remove an event listener without a valid "
140 << "extension ID nor listener URL";
144 void ExtensionMessageFilter::OnExtensionAddLazyListener(
145 const std::string
& extension_id
, const std::string
& event_name
) {
146 EventRouter
* router
= EventRouter::Get(browser_context_
);
149 router
->AddLazyEventListener(event_name
, extension_id
);
152 void ExtensionMessageFilter::OnExtensionAttachGuest(
154 int element_instance_id
,
155 int guest_instance_id
,
156 const base::DictionaryValue
& params
) {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
158 extensions::GuestViewManager
* manager
=
159 extensions::GuestViewManager::FromBrowserContext(browser_context_
);
163 manager
->AttachGuest(render_process_id_
,
170 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
171 const std::string
& extension_id
, const std::string
& event_name
) {
172 EventRouter
* router
= EventRouter::Get(browser_context_
);
175 router
->RemoveLazyEventListener(event_name
, extension_id
);
178 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
179 const std::string
& extension_id
,
180 const std::string
& event_name
,
181 const base::DictionaryValue
& filter
,
183 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
186 EventRouter
* router
= EventRouter::Get(browser_context_
);
189 router
->AddFilteredEventListener(
190 event_name
, process
, extension_id
, filter
, lazy
);
193 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
194 const std::string
& extension_id
,
195 const std::string
& event_name
,
196 const base::DictionaryValue
& filter
,
198 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
201 EventRouter
* router
= EventRouter::Get(browser_context_
);
204 router
->RemoveFilteredEventListener(
205 event_name
, process
, extension_id
, filter
, lazy
);
208 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
209 const std::string
& extension_id
, int sequence_id
) {
210 ProcessManager
* process_manager
=
211 ExtensionSystem::Get(browser_context_
)->process_manager();
213 process_manager
->OnShouldSuspendAck(extension_id
, sequence_id
);
216 void ExtensionMessageFilter::OnExtensionSuspendAck(
217 const std::string
& extension_id
) {
218 ProcessManager
* process_manager
=
219 ExtensionSystem::Get(browser_context_
)->process_manager();
221 process_manager
->OnSuspendAck(extension_id
);
224 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
225 const std::vector
<std::string
>& blob_uuids
) {
226 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
229 BlobHolder::FromRenderProcessHost(process
)->DropBlobs(blob_uuids
);
232 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id
) {
233 static int next_unique_id
= 0;
234 *unique_id
= ++next_unique_id
;
237 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id
) {
238 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
239 render_process_id_
, route_id
);
242 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
244 const ExtensionHostMsg_Request_Params
& params
) {
245 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
246 ExtensionFunctionDispatcher::DispatchOnIOThread(
247 extension_info_map_
.get(),
250 weak_ptr_factory_
.GetWeakPtr(),
255 } // namespace extensions