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_frame_host.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/resource_dispatcher_host.h"
13 #include "extensions/browser/blob_holder.h"
14 #include "extensions/browser/event_router.h"
15 #include "extensions/browser/extension_function_dispatcher.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/browser/guest_view/guest_view_base.h"
18 #include "extensions/browser/guest_view/guest_view_manager.h"
19 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_constants.h"
20 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
21 #include "extensions/browser/info_map.h"
22 #include "extensions/browser/process_manager.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_messages.h"
25 #include "ipc/ipc_message_macros.h"
27 using content::BrowserThread
;
28 using content::RenderProcessHost
;
30 namespace extensions
{
32 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id
,
33 content::BrowserContext
* context
)
34 : BrowserMessageFilter(ExtensionMsgStart
),
35 render_process_id_(render_process_id
),
36 browser_context_(context
),
37 extension_info_map_(ExtensionSystem::Get(context
)->info_map()),
38 weak_ptr_factory_(this) {
39 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
42 ExtensionMessageFilter::~ExtensionMessageFilter() {
43 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
46 void ExtensionMessageFilter::OverrideThreadForMessage(
47 const IPC::Message
& message
,
48 BrowserThread::ID
* thread
) {
49 switch (message
.type()) {
50 case ExtensionHostMsg_AddListener::ID
:
51 case ExtensionHostMsg_AttachGuest::ID
:
52 case ExtensionHostMsg_RemoveListener::ID
:
53 case ExtensionHostMsg_AddLazyListener::ID
:
54 case ExtensionHostMsg_CreateMimeHandlerViewGuest::ID
:
55 case ExtensionHostMsg_RemoveLazyListener::ID
:
56 case ExtensionHostMsg_AddFilteredListener::ID
:
57 case ExtensionHostMsg_RemoveFilteredListener::ID
:
58 case ExtensionHostMsg_ShouldSuspendAck::ID
:
59 case ExtensionHostMsg_SuspendAck::ID
:
60 case ExtensionHostMsg_TransferBlobsAck::ID
:
61 *thread
= BrowserThread::UI
;
68 void ExtensionMessageFilter::OnDestruct() const {
69 // Destroy the filter on the IO thread since that's where its weak pointers
71 BrowserThread::DeleteOnIOThread::Destruct(this);
74 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message
& message
) {
76 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter
, message
)
77 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener
,
78 OnExtensionAddListener
)
79 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener
,
80 OnExtensionRemoveListener
)
81 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener
,
82 OnExtensionAddLazyListener
)
83 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AttachGuest
,
84 OnExtensionAttachGuest
)
85 IPC_MESSAGE_HANDLER(ExtensionHostMsg_CreateMimeHandlerViewGuest
,
86 OnExtensionCreateMimeHandlerViewGuest
)
87 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener
,
88 OnExtensionRemoveLazyListener
)
89 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener
,
90 OnExtensionAddFilteredListener
)
91 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener
,
92 OnExtensionRemoveFilteredListener
)
93 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck
,
94 OnExtensionShouldSuspendAck
)
95 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck
,
96 OnExtensionSuspendAck
)
97 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck
,
98 OnExtensionTransferBlobsAck
)
99 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID
,
100 OnExtensionGenerateUniqueID
)
101 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests
,
102 OnExtensionResumeRequests
);
103 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread
,
104 OnExtensionRequestForIOThread
)
105 IPC_MESSAGE_UNHANDLED(handled
= false)
106 IPC_END_MESSAGE_MAP()
110 void ExtensionMessageFilter::OnExtensionAddListener(
111 const std::string
& extension_id
,
112 const GURL
& listener_url
,
113 const std::string
& event_name
) {
114 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
117 EventRouter
* router
= EventRouter::Get(browser_context_
);
121 if (crx_file::id_util::IdIsValid(extension_id
)) {
122 router
->AddEventListener(event_name
, process
, extension_id
);
123 } else if (listener_url
.is_valid()) {
124 router
->AddEventListenerForURL(event_name
, process
, listener_url
);
126 NOTREACHED() << "Tried to add an event listener without a valid "
127 << "extension ID nor listener URL";
131 void ExtensionMessageFilter::OnExtensionRemoveListener(
132 const std::string
& extension_id
,
133 const GURL
& listener_url
,
134 const std::string
& event_name
) {
135 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
138 EventRouter
* router
= EventRouter::Get(browser_context_
);
142 if (crx_file::id_util::IdIsValid(extension_id
)) {
143 router
->RemoveEventListener(event_name
, process
, extension_id
);
144 } else if (listener_url
.is_valid()) {
145 router
->RemoveEventListenerForURL(event_name
, process
, listener_url
);
147 NOTREACHED() << "Tried to remove an event listener without a valid "
148 << "extension ID nor listener URL";
152 void ExtensionMessageFilter::OnExtensionAddLazyListener(
153 const std::string
& extension_id
, const std::string
& event_name
) {
154 EventRouter
* router
= EventRouter::Get(browser_context_
);
157 router
->AddLazyEventListener(event_name
, extension_id
);
160 void ExtensionMessageFilter::OnExtensionAttachGuest(
162 int element_instance_id
,
163 int guest_instance_id
,
164 const base::DictionaryValue
& params
) {
165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
166 GuestViewManager
* manager
=
167 GuestViewManager::FromBrowserContext(browser_context_
);
171 manager
->AttachGuest(render_process_id_
,
178 void ExtensionMessageFilter::OnExtensionCreateMimeHandlerViewGuest(
180 const std::string
& src
,
181 const std::string
& mime_type
,
182 int element_instance_id
) {
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
184 GuestViewManager
* manager
=
185 GuestViewManager::FromBrowserContext(browser_context_
);
189 content::RenderFrameHost
* rfh
=
190 content::RenderFrameHost::FromID(render_process_id_
, render_frame_id
);
191 content::WebContents
* embedder_web_contents
=
192 content::WebContents::FromRenderFrameHost(rfh
);
193 if (!embedder_web_contents
)
196 GuestViewManager::WebContentsCreatedCallback callback
=
197 base::Bind(&ExtensionMessageFilter::MimeHandlerViewGuestCreatedCallback
,
203 base::DictionaryValue create_params
;
204 create_params
.SetString(mime_handler_view::kMimeType
, mime_type
);
205 manager
->CreateGuest(MimeHandlerViewGuest::Type
,
207 embedder_web_contents
,
212 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
213 const std::string
& extension_id
, const std::string
& event_name
) {
214 EventRouter
* router
= EventRouter::Get(browser_context_
);
217 router
->RemoveLazyEventListener(event_name
, extension_id
);
220 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
221 const std::string
& extension_id
,
222 const std::string
& event_name
,
223 const base::DictionaryValue
& filter
,
225 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
228 EventRouter
* router
= EventRouter::Get(browser_context_
);
231 router
->AddFilteredEventListener(
232 event_name
, process
, extension_id
, filter
, lazy
);
235 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
236 const std::string
& extension_id
,
237 const std::string
& event_name
,
238 const base::DictionaryValue
& filter
,
240 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
243 EventRouter
* router
= EventRouter::Get(browser_context_
);
246 router
->RemoveFilteredEventListener(
247 event_name
, process
, extension_id
, filter
, lazy
);
250 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
251 const std::string
& extension_id
, int sequence_id
) {
252 ProcessManager
* process_manager
=
253 ExtensionSystem::Get(browser_context_
)->process_manager();
255 process_manager
->OnShouldSuspendAck(extension_id
, sequence_id
);
258 void ExtensionMessageFilter::OnExtensionSuspendAck(
259 const std::string
& extension_id
) {
260 ProcessManager
* process_manager
=
261 ExtensionSystem::Get(browser_context_
)->process_manager();
263 process_manager
->OnSuspendAck(extension_id
);
266 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
267 const std::vector
<std::string
>& blob_uuids
) {
268 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
271 BlobHolder::FromRenderProcessHost(process
)->DropBlobs(blob_uuids
);
274 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id
) {
275 static int next_unique_id
= 0;
276 *unique_id
= ++next_unique_id
;
279 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id
) {
280 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
281 render_process_id_
, route_id
);
284 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
286 const ExtensionHostMsg_Request_Params
& params
) {
287 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
288 ExtensionFunctionDispatcher::DispatchOnIOThread(
289 extension_info_map_
.get(),
292 weak_ptr_factory_
.GetWeakPtr(),
297 void ExtensionMessageFilter::MimeHandlerViewGuestCreatedCallback(
298 int element_instance_id
,
299 int embedder_render_process_id
,
300 int embedder_render_frame_id
,
301 const std::string
& src
,
302 content::WebContents
* web_contents
) {
303 GuestViewManager
* manager
=
304 GuestViewManager::FromBrowserContext(browser_context_
);
308 MimeHandlerViewGuest
* guest_view
=
309 MimeHandlerViewGuest::FromWebContents(web_contents
);
312 int guest_instance_id
= guest_view
->guest_instance_id();
314 content::RenderFrameHost
* rfh
= content::RenderFrameHost::FromID(
315 embedder_render_process_id
, embedder_render_frame_id
);
319 base::DictionaryValue attach_params
;
320 attach_params
.SetString(mime_handler_view::kSrc
, src
);
321 manager
->AttachGuest(embedder_render_process_id
,
322 rfh
->GetRenderViewHost()->GetRoutingID(),
328 new ExtensionMsg_CreateMimeHandlerViewGuestACK(element_instance_id
);
329 msg
->set_routing_id(rfh
->GetRoutingID());
333 } // namespace extensions