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/info_map.h"
18 #include "extensions/browser/process_manager.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_messages.h"
21 #include "ipc/ipc_message_macros.h"
23 using content::BrowserThread
;
24 using content::RenderProcessHost
;
26 namespace extensions
{
28 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id
,
29 content::BrowserContext
* context
)
30 : BrowserMessageFilter(ExtensionMsgStart
),
31 render_process_id_(render_process_id
),
32 browser_context_(context
),
33 extension_info_map_(ExtensionSystem::Get(context
)->info_map()),
34 weak_ptr_factory_(this) {
35 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
38 ExtensionMessageFilter::~ExtensionMessageFilter() {
39 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
42 void ExtensionMessageFilter::OverrideThreadForMessage(
43 const IPC::Message
& message
,
44 BrowserThread::ID
* thread
) {
45 switch (message
.type()) {
46 case ExtensionHostMsg_AddListener::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_RemoveLazyListener
,
78 OnExtensionRemoveLazyListener
)
79 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener
,
80 OnExtensionAddFilteredListener
)
81 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener
,
82 OnExtensionRemoveFilteredListener
)
83 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck
,
84 OnExtensionShouldSuspendAck
)
85 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck
,
86 OnExtensionSuspendAck
)
87 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck
,
88 OnExtensionTransferBlobsAck
)
89 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID
,
90 OnExtensionGenerateUniqueID
)
91 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests
,
92 OnExtensionResumeRequests
);
93 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread
,
94 OnExtensionRequestForIOThread
)
95 IPC_MESSAGE_UNHANDLED(handled
= false)
100 void ExtensionMessageFilter::OnExtensionAddListener(
101 const std::string
& extension_id
,
102 const GURL
& listener_url
,
103 const std::string
& event_name
) {
104 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
107 EventRouter
* router
= EventRouter::Get(browser_context_
);
111 if (crx_file::id_util::IdIsValid(extension_id
)) {
112 router
->AddEventListener(event_name
, process
, extension_id
);
113 } else if (listener_url
.is_valid()) {
114 router
->AddEventListenerForURL(event_name
, process
, listener_url
);
116 NOTREACHED() << "Tried to add an event listener without a valid "
117 << "extension ID nor listener URL";
121 void ExtensionMessageFilter::OnExtensionRemoveListener(
122 const std::string
& extension_id
,
123 const GURL
& listener_url
,
124 const std::string
& event_name
) {
125 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
128 EventRouter
* router
= EventRouter::Get(browser_context_
);
132 if (crx_file::id_util::IdIsValid(extension_id
)) {
133 router
->RemoveEventListener(event_name
, process
, extension_id
);
134 } else if (listener_url
.is_valid()) {
135 router
->RemoveEventListenerForURL(event_name
, process
, listener_url
);
137 NOTREACHED() << "Tried to remove an event listener without a valid "
138 << "extension ID nor listener URL";
142 void ExtensionMessageFilter::OnExtensionAddLazyListener(
143 const std::string
& extension_id
, const std::string
& event_name
) {
144 EventRouter
* router
= EventRouter::Get(browser_context_
);
147 router
->AddLazyEventListener(event_name
, extension_id
);
150 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
151 const std::string
& extension_id
, const std::string
& event_name
) {
152 EventRouter
* router
= EventRouter::Get(browser_context_
);
155 router
->RemoveLazyEventListener(event_name
, extension_id
);
158 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
159 const std::string
& extension_id
,
160 const std::string
& event_name
,
161 const base::DictionaryValue
& filter
,
163 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
166 EventRouter
* router
= EventRouter::Get(browser_context_
);
169 router
->AddFilteredEventListener(
170 event_name
, process
, extension_id
, filter
, lazy
);
173 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
174 const std::string
& extension_id
,
175 const std::string
& event_name
,
176 const base::DictionaryValue
& filter
,
178 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
181 EventRouter
* router
= EventRouter::Get(browser_context_
);
184 router
->RemoveFilteredEventListener(
185 event_name
, process
, extension_id
, filter
, lazy
);
188 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
189 const std::string
& extension_id
, int sequence_id
) {
190 ProcessManager::Get(browser_context_
)
191 ->OnShouldSuspendAck(extension_id
, sequence_id
);
194 void ExtensionMessageFilter::OnExtensionSuspendAck(
195 const std::string
& extension_id
) {
196 ProcessManager::Get(browser_context_
)->OnSuspendAck(extension_id
);
199 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
200 const std::vector
<std::string
>& blob_uuids
) {
201 RenderProcessHost
* process
= RenderProcessHost::FromID(render_process_id_
);
204 BlobHolder::FromRenderProcessHost(process
)->DropBlobs(blob_uuids
);
207 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id
) {
208 static int next_unique_id
= 0;
209 *unique_id
= ++next_unique_id
;
212 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id
) {
213 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
214 render_process_id_
, route_id
);
217 void ExtensionMessageFilter::OnExtensionRequestForIOThread(
219 const ExtensionHostMsg_Request_Params
& params
) {
220 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
221 ExtensionFunctionDispatcher::DispatchOnIOThread(
222 extension_info_map_
.get(),
225 weak_ptr_factory_
.GetWeakPtr(),
230 } // namespace extensions