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
& view_id
,
181 int element_instance_id
,
182 const gfx::Size
& element_size
) {
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
,
204 base::DictionaryValue create_params
;
205 create_params
.SetString(mime_handler_view::kViewId
, view_id
);
206 create_params
.SetInteger(guestview::kElementWidth
, element_size
.width());
207 create_params
.SetInteger(guestview::kElementHeight
, element_size
.height());
208 manager
->CreateGuest(MimeHandlerViewGuest::Type
,
209 embedder_web_contents
,
214 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
215 const std::string
& extension_id
, const std::string
& event_name
) {
216 EventRouter
* router
= EventRouter::Get(browser_context_
);
219 router
->RemoveLazyEventListener(event_name
, extension_id
);
222 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
223 const std::string
& extension_id
,
224 const std::string
& event_name
,
225 const base::DictionaryValue
& filter
,
227 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
230 EventRouter
* router
= EventRouter::Get(browser_context_
);
233 router
->AddFilteredEventListener(
234 event_name
, process
, extension_id
, filter
, lazy
);
237 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
238 const std::string
& extension_id
,
239 const std::string
& event_name
,
240 const base::DictionaryValue
& filter
,
242 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
245 EventRouter
* router
= EventRouter::Get(browser_context_
);
248 router
->RemoveFilteredEventListener(
249 event_name
, process
, extension_id
, filter
, lazy
);
252 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
253 const std::string
& extension_id
, int sequence_id
) {
254 ProcessManager::Get(browser_context_
)
255 ->OnShouldSuspendAck(extension_id
, sequence_id
);
258 void ExtensionMessageFilter::OnExtensionSuspendAck(
259 const std::string
& extension_id
) {
260 ProcessManager::Get(browser_context_
)->OnSuspendAck(extension_id
);
263 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
264 const std::vector
<std::string
>& blob_uuids
) {
265 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
268 BlobHolder::FromRenderProcessHost(process
)->DropBlobs(blob_uuids
);
271 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id
) {
272 static int next_unique_id
= 0;
273 *unique_id
= ++next_unique_id
;
276 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id
) {
277 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
278 render_process_id_
, route_id
);
281 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
283 const ExtensionHostMsg_Request_Params
& params
) {
284 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
285 ExtensionFunctionDispatcher::DispatchOnIOThread(
286 extension_info_map_
.get(),
289 weak_ptr_factory_
.GetWeakPtr(),
294 void ExtensionMessageFilter::MimeHandlerViewGuestCreatedCallback(
295 int element_instance_id
,
296 int embedder_render_process_id
,
297 int embedder_render_frame_id
,
298 const gfx::Size
& element_size
,
299 content::WebContents
* web_contents
) {
300 GuestViewManager
* manager
=
301 GuestViewManager::FromBrowserContext(browser_context_
);
305 MimeHandlerViewGuest
* guest_view
=
306 MimeHandlerViewGuest::FromWebContents(web_contents
);
309 int guest_instance_id
= guest_view
->guest_instance_id();
311 content::RenderFrameHost
* rfh
= content::RenderFrameHost::FromID(
312 embedder_render_process_id
, embedder_render_frame_id
);
316 base::DictionaryValue attach_params
;
317 attach_params
.SetInteger(guestview::kElementWidth
, element_size
.width());
318 attach_params
.SetInteger(guestview::kElementHeight
, element_size
.height());
319 manager
->AttachGuest(embedder_render_process_id
,
320 rfh
->GetRenderViewHost()->GetRoutingID(),
326 new ExtensionMsg_CreateMimeHandlerViewGuestACK(element_instance_id
));
329 } // namespace extensions