Add chrome.usb.getConfiguration and expose extra descriptors.
[chromium-blink-merge.git] / extensions / browser / extension_message_filter.cc
blobab24809253b0160fbdd16a160878bafbf0dcccfb
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;
62 break;
63 default:
64 break;
68 void ExtensionMessageFilter::OnDestruct() const {
69 // Destroy the filter on the IO thread since that's where its weak pointers
70 // are being used.
71 BrowserThread::DeleteOnIOThread::Destruct(this);
74 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) {
75 bool handled = true;
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()
107 return handled;
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_);
115 if (!process)
116 return;
117 EventRouter* router = EventRouter::Get(browser_context_);
118 if (!router)
119 return;
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);
125 } else {
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_);
136 if (!process)
137 return;
138 EventRouter* router = EventRouter::Get(browser_context_);
139 if (!router)
140 return;
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);
146 } else {
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_);
155 if (!router)
156 return;
157 router->AddLazyEventListener(event_name, extension_id);
160 void ExtensionMessageFilter::OnExtensionAttachGuest(
161 int routing_id,
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_);
168 if (!manager)
169 return;
171 manager->AttachGuest(render_process_id_,
172 routing_id,
173 element_instance_id,
174 guest_instance_id,
175 params);
178 void ExtensionMessageFilter::OnExtensionCreateMimeHandlerViewGuest(
179 int render_frame_id,
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_);
186 if (!manager)
187 return;
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)
194 return;
196 GuestViewManager::WebContentsCreatedCallback callback =
197 base::Bind(&ExtensionMessageFilter::MimeHandlerViewGuestCreatedCallback,
198 this,
199 element_instance_id,
200 render_process_id_,
201 render_frame_id,
202 src);
203 base::DictionaryValue create_params;
204 create_params.SetString(mime_handler_view::kMimeType, mime_type);
205 manager->CreateGuest(MimeHandlerViewGuest::Type,
207 embedder_web_contents,
208 create_params,
209 callback);
212 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
213 const std::string& extension_id, const std::string& event_name) {
214 EventRouter* router = EventRouter::Get(browser_context_);
215 if (!router)
216 return;
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,
224 bool lazy) {
225 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
226 if (!process)
227 return;
228 EventRouter* router = EventRouter::Get(browser_context_);
229 if (!router)
230 return;
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,
239 bool lazy) {
240 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
241 if (!process)
242 return;
243 EventRouter* router = EventRouter::Get(browser_context_);
244 if (!router)
245 return;
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();
254 if (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();
262 if (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_);
269 if (!process)
270 return;
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(
285 int routing_id,
286 const ExtensionHostMsg_Request_Params& params) {
287 DCHECK_CURRENTLY_ON(BrowserThread::IO);
288 ExtensionFunctionDispatcher::DispatchOnIOThread(
289 extension_info_map_.get(),
290 browser_context_,
291 render_process_id_,
292 weak_ptr_factory_.GetWeakPtr(),
293 routing_id,
294 params);
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_);
305 if (!manager)
306 return;
308 MimeHandlerViewGuest* guest_view =
309 MimeHandlerViewGuest::FromWebContents(web_contents);
310 if (!guest_view)
311 return;
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);
316 if (!rfh)
317 return;
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(),
323 element_instance_id,
324 guest_instance_id,
325 attach_params);
327 IPC::Message* msg =
328 new ExtensionMsg_CreateMimeHandlerViewGuestACK(element_instance_id);
329 msg->set_routing_id(rfh->GetRoutingID());
330 rfh->Send(msg);
333 } // namespace extensions