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
& content_url
,
182 const std::string
& mime_type
,
183 int element_instance_id
) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
185 GuestViewManager
* manager
=
186 GuestViewManager::FromBrowserContext(browser_context_
);
190 content::RenderFrameHost
* rfh
=
191 content::RenderFrameHost::FromID(render_process_id_
, render_frame_id
);
192 content::WebContents
* embedder_web_contents
=
193 content::WebContents::FromRenderFrameHost(rfh
);
194 if (!embedder_web_contents
)
197 GuestViewManager::WebContentsCreatedCallback callback
=
198 base::Bind(&ExtensionMessageFilter::MimeHandlerViewGuestCreatedCallback
,
204 base::DictionaryValue create_params
;
205 create_params
.SetString(mime_handler_view::kMimeType
, mime_type
);
206 create_params
.SetString(mime_handler_view::kSrc
, src
);
207 create_params
.SetString(mime_handler_view::kContentUrl
, content_url
);
208 manager
->CreateGuest(MimeHandlerViewGuest::Type
,
210 embedder_web_contents
,
215 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
216 const std::string
& extension_id
, const std::string
& event_name
) {
217 EventRouter
* router
= EventRouter::Get(browser_context_
);
220 router
->RemoveLazyEventListener(event_name
, extension_id
);
223 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
224 const std::string
& extension_id
,
225 const std::string
& event_name
,
226 const base::DictionaryValue
& filter
,
228 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
231 EventRouter
* router
= EventRouter::Get(browser_context_
);
234 router
->AddFilteredEventListener(
235 event_name
, process
, extension_id
, filter
, lazy
);
238 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
239 const std::string
& extension_id
,
240 const std::string
& event_name
,
241 const base::DictionaryValue
& filter
,
243 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
246 EventRouter
* router
= EventRouter::Get(browser_context_
);
249 router
->RemoveFilteredEventListener(
250 event_name
, process
, extension_id
, filter
, lazy
);
253 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
254 const std::string
& extension_id
, int sequence_id
) {
255 ProcessManager::Get(browser_context_
)
256 ->OnShouldSuspendAck(extension_id
, sequence_id
);
259 void ExtensionMessageFilter::OnExtensionSuspendAck(
260 const std::string
& extension_id
) {
261 ProcessManager::Get(browser_context_
)->OnSuspendAck(extension_id
);
264 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
265 const std::vector
<std::string
>& blob_uuids
) {
266 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
269 BlobHolder::FromRenderProcessHost(process
)->DropBlobs(blob_uuids
);
272 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id
) {
273 static int next_unique_id
= 0;
274 *unique_id
= ++next_unique_id
;
277 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id
) {
278 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
279 render_process_id_
, route_id
);
282 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
284 const ExtensionHostMsg_Request_Params
& params
) {
285 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
286 ExtensionFunctionDispatcher::DispatchOnIOThread(
287 extension_info_map_
.get(),
290 weak_ptr_factory_
.GetWeakPtr(),
295 void ExtensionMessageFilter::MimeHandlerViewGuestCreatedCallback(
296 int element_instance_id
,
297 int embedder_render_process_id
,
298 int embedder_render_frame_id
,
299 const std::string
& src
,
300 content::WebContents
* web_contents
) {
301 GuestViewManager
* manager
=
302 GuestViewManager::FromBrowserContext(browser_context_
);
306 MimeHandlerViewGuest
* guest_view
=
307 MimeHandlerViewGuest::FromWebContents(web_contents
);
310 int guest_instance_id
= guest_view
->guest_instance_id();
312 content::RenderFrameHost
* rfh
= content::RenderFrameHost::FromID(
313 embedder_render_process_id
, embedder_render_frame_id
);
317 base::DictionaryValue attach_params
;
318 attach_params
.SetString(mime_handler_view::kSrc
, src
);
319 manager
->AttachGuest(embedder_render_process_id
,
320 rfh
->GetRenderViewHost()->GetRoutingID(),
326 new ExtensionMsg_CreateMimeHandlerViewGuestACK(element_instance_id
);
327 msg
->set_routing_id(rfh
->GetRoutingID());
331 } // namespace extensions