OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/browser/extension_message_filter.h" | 5 #include "extensions/browser/extension_message_filter.h" |
6 | 6 |
7 #include "base/memory/singleton.h" | |
7 #include "components/crx_file/id_util.h" | 8 #include "components/crx_file/id_util.h" |
9 #include "components/keyed_service/content/browser_context_keyed_service_shutdow n_notifier_factory.h" | |
8 #include "content/public/browser/browser_thread.h" | 10 #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_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" | 12 #include "extensions/browser/blob_holder.h" |
14 #include "extensions/browser/event_router.h" | 13 #include "extensions/browser/event_router.h" |
15 #include "extensions/browser/extension_function_dispatcher.h" | |
16 #include "extensions/browser/extension_system.h" | 14 #include "extensions/browser/extension_system.h" |
17 #include "extensions/browser/info_map.h" | 15 #include "extensions/browser/extension_system_provider.h" |
16 #include "extensions/browser/extensions_browser_client.h" | |
18 #include "extensions/browser/process_manager.h" | 17 #include "extensions/browser/process_manager.h" |
18 #include "extensions/browser/process_manager_factory.h" | |
19 #include "extensions/common/extension.h" | 19 #include "extensions/common/extension.h" |
20 #include "extensions/common/extension_messages.h" | 20 #include "extensions/common/extension_messages.h" |
21 #include "ipc/ipc_message_macros.h" | 21 #include "ipc/ipc_message_macros.h" |
22 | 22 |
23 using content::BrowserThread; | 23 using content::BrowserThread; |
24 using content::RenderProcessHost; | 24 using content::RenderProcessHost; |
25 | 25 |
26 namespace extensions { | 26 namespace extensions { |
27 | 27 |
28 namespace { | |
29 | |
30 class ShutdownNotifierFactory | |
31 : public BrowserContextKeyedServiceShutdownNotifierFactory { | |
32 public: | |
33 static ShutdownNotifierFactory* GetInstance() { | |
34 return Singleton<ShutdownNotifierFactory>::get(); | |
35 } | |
36 | |
37 private: | |
38 friend struct DefaultSingletonTraits<ShutdownNotifierFactory>; | |
39 | |
40 ShutdownNotifierFactory() | |
41 : BrowserContextKeyedServiceShutdownNotifierFactory( | |
42 "ExtensionMessageFilter") { | |
43 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | |
44 DependsOn(ProcessManagerFactory::GetInstance()); | |
45 } | |
46 ~ShutdownNotifierFactory() override {} | |
47 | |
48 DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory); | |
49 }; | |
50 | |
51 } // namespace | |
52 | |
28 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id, | 53 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id, |
29 content::BrowserContext* context) | 54 content::BrowserContext* context) |
30 : BrowserMessageFilter(ExtensionMsgStart), | 55 : BrowserMessageFilter(ExtensionMsgStart), |
31 render_process_id_(render_process_id), | 56 render_process_id_(render_process_id), |
32 browser_context_(context), | 57 extension_system_(ExtensionSystem::Get(context)), |
33 extension_info_map_(ExtensionSystem::Get(context)->info_map()), | 58 process_manager_(ProcessManager::Get(context)) { |
34 weak_ptr_factory_(this) { | 59 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
60 shutdown_notifier_ = | |
61 ShutdownNotifierFactory::GetInstance()->Get(context)->Subscribe( | |
62 base::Bind(&ExtensionMessageFilter::ShutdownOnUIThread, | |
63 base::Unretained(this))); | |
64 } | |
65 | |
66 void ExtensionMessageFilter::EnsureShutdownNotifierFactoryBuilt() { | |
67 ShutdownNotifierFactory::GetInstance(); | |
68 } | |
69 | |
70 ExtensionMessageFilter::~ExtensionMessageFilter() { | |
35 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 71 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
36 } | 72 } |
37 | 73 |
38 ExtensionMessageFilter::~ExtensionMessageFilter() { | 74 void ExtensionMessageFilter::ShutdownOnUIThread() { |
39 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 75 extension_system_ = nullptr; |
76 process_manager_ = nullptr; | |
77 shutdown_notifier_.reset(); | |
40 } | 78 } |
41 | 79 |
42 void ExtensionMessageFilter::OverrideThreadForMessage( | 80 void ExtensionMessageFilter::OverrideThreadForMessage( |
43 const IPC::Message& message, | 81 const IPC::Message& message, |
44 BrowserThread::ID* thread) { | 82 BrowserThread::ID* thread) { |
45 switch (message.type()) { | 83 switch (message.type()) { |
46 case ExtensionHostMsg_AddListener::ID: | 84 case ExtensionHostMsg_AddListener::ID: |
47 case ExtensionHostMsg_RemoveListener::ID: | 85 case ExtensionHostMsg_RemoveListener::ID: |
48 case ExtensionHostMsg_AddLazyListener::ID: | 86 case ExtensionHostMsg_AddLazyListener::ID: |
49 case ExtensionHostMsg_RemoveLazyListener::ID: | 87 case ExtensionHostMsg_RemoveLazyListener::ID: |
50 case ExtensionHostMsg_AddFilteredListener::ID: | 88 case ExtensionHostMsg_AddFilteredListener::ID: |
51 case ExtensionHostMsg_RemoveFilteredListener::ID: | 89 case ExtensionHostMsg_RemoveFilteredListener::ID: |
52 case ExtensionHostMsg_ShouldSuspendAck::ID: | 90 case ExtensionHostMsg_ShouldSuspendAck::ID: |
53 case ExtensionHostMsg_SuspendAck::ID: | 91 case ExtensionHostMsg_SuspendAck::ID: |
54 case ExtensionHostMsg_TransferBlobsAck::ID: | 92 case ExtensionHostMsg_TransferBlobsAck::ID: |
55 *thread = BrowserThread::UI; | 93 *thread = BrowserThread::UI; |
56 break; | 94 break; |
57 default: | 95 default: |
58 break; | 96 break; |
59 } | 97 } |
60 } | 98 } |
61 | 99 |
62 void ExtensionMessageFilter::OnDestruct() const { | 100 void ExtensionMessageFilter::OnDestruct() const { |
63 // Destroy the filter on the IO thread since that's where its weak pointers | 101 BrowserThread::DeleteOnUIThread::Destruct(this); |
64 // are being used. | |
65 BrowserThread::DeleteOnIOThread::Destruct(this); | |
66 } | 102 } |
67 | 103 |
68 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) { | 104 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) { |
69 bool handled = true; | 105 bool handled = true; |
70 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message) | 106 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message) |
71 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, | 107 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, |
72 OnExtensionAddListener) | 108 OnExtensionAddListener) |
73 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener, | 109 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener, |
74 OnExtensionRemoveListener) | 110 OnExtensionRemoveListener) |
75 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener, | 111 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener, |
76 OnExtensionAddLazyListener) | 112 OnExtensionAddLazyListener) |
77 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, | 113 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, |
78 OnExtensionRemoveLazyListener) | 114 OnExtensionRemoveLazyListener) |
79 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, | 115 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, |
80 OnExtensionAddFilteredListener) | 116 OnExtensionAddFilteredListener) |
81 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, | 117 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, |
82 OnExtensionRemoveFilteredListener) | 118 OnExtensionRemoveFilteredListener) |
83 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck, | 119 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck, |
84 OnExtensionShouldSuspendAck) | 120 OnExtensionShouldSuspendAck) |
85 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, | 121 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, |
86 OnExtensionSuspendAck) | 122 OnExtensionSuspendAck) |
87 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck, | 123 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck, |
88 OnExtensionTransferBlobsAck) | 124 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) | 125 IPC_MESSAGE_UNHANDLED(handled = false) |
96 IPC_END_MESSAGE_MAP() | 126 IPC_END_MESSAGE_MAP() |
97 return handled; | 127 return handled; |
98 } | 128 } |
99 | 129 |
100 void ExtensionMessageFilter::OnExtensionAddListener( | 130 void ExtensionMessageFilter::OnExtensionAddListener( |
101 const std::string& extension_id, | 131 const std::string& extension_id, |
102 const GURL& listener_url, | 132 const GURL& listener_url, |
103 const std::string& event_name) { | 133 const std::string& event_name) { |
104 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 134 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
105 if (!process) | 135 if (!process) |
106 return; | 136 return; |
107 EventRouter* router = EventRouter::Get(browser_context_); | 137 |
138 if (!extension_system_) | |
139 return; | |
140 | |
141 EventRouter* router = extension_system_->event_router(); | |
108 if (!router) | 142 if (!router) |
109 return; | 143 return; |
110 | 144 |
111 if (crx_file::id_util::IdIsValid(extension_id)) { | 145 if (crx_file::id_util::IdIsValid(extension_id)) { |
112 router->AddEventListener(event_name, process, extension_id); | 146 router->AddEventListener(event_name, process, extension_id); |
113 } else if (listener_url.is_valid()) { | 147 } else if (listener_url.is_valid()) { |
114 router->AddEventListenerForURL(event_name, process, listener_url); | 148 router->AddEventListenerForURL(event_name, process, listener_url); |
115 } else { | 149 } else { |
116 NOTREACHED() << "Tried to add an event listener without a valid " | 150 NOTREACHED() << "Tried to add an event listener without a valid " |
117 << "extension ID nor listener URL"; | 151 << "extension ID nor listener URL"; |
118 } | 152 } |
119 } | 153 } |
120 | 154 |
121 void ExtensionMessageFilter::OnExtensionRemoveListener( | 155 void ExtensionMessageFilter::OnExtensionRemoveListener( |
122 const std::string& extension_id, | 156 const std::string& extension_id, |
123 const GURL& listener_url, | 157 const GURL& listener_url, |
124 const std::string& event_name) { | 158 const std::string& event_name) { |
125 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 159 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
126 if (!process) | 160 if (!process) |
127 return; | 161 return; |
128 EventRouter* router = EventRouter::Get(browser_context_); | 162 |
163 if (!extension_system_) | |
not at google - send to devlin
2015/02/10 18:37:41
Is it possible to do all of these extension system
Bernhard Bauer
2015/02/10 19:02:34
Done. It does mean that we don't check anymore whe
| |
164 return; | |
165 | |
166 EventRouter* router = extension_system_->event_router(); | |
129 if (!router) | 167 if (!router) |
130 return; | 168 return; |
131 | 169 |
132 if (crx_file::id_util::IdIsValid(extension_id)) { | 170 if (crx_file::id_util::IdIsValid(extension_id)) { |
133 router->RemoveEventListener(event_name, process, extension_id); | 171 router->RemoveEventListener(event_name, process, extension_id); |
134 } else if (listener_url.is_valid()) { | 172 } else if (listener_url.is_valid()) { |
135 router->RemoveEventListenerForURL(event_name, process, listener_url); | 173 router->RemoveEventListenerForURL(event_name, process, listener_url); |
136 } else { | 174 } else { |
137 NOTREACHED() << "Tried to remove an event listener without a valid " | 175 NOTREACHED() << "Tried to remove an event listener without a valid " |
138 << "extension ID nor listener URL"; | 176 << "extension ID nor listener URL"; |
139 } | 177 } |
140 } | 178 } |
141 | 179 |
142 void ExtensionMessageFilter::OnExtensionAddLazyListener( | 180 void ExtensionMessageFilter::OnExtensionAddLazyListener( |
143 const std::string& extension_id, const std::string& event_name) { | 181 const std::string& extension_id, const std::string& event_name) { |
144 EventRouter* router = EventRouter::Get(browser_context_); | 182 if (!extension_system_) |
183 return; | |
184 | |
185 EventRouter* router = extension_system_->event_router(); | |
145 if (!router) | 186 if (!router) |
146 return; | 187 return; |
188 | |
147 router->AddLazyEventListener(event_name, extension_id); | 189 router->AddLazyEventListener(event_name, extension_id); |
148 } | 190 } |
149 | 191 |
150 void ExtensionMessageFilter::OnExtensionRemoveLazyListener( | 192 void ExtensionMessageFilter::OnExtensionRemoveLazyListener( |
151 const std::string& extension_id, const std::string& event_name) { | 193 const std::string& extension_id, const std::string& event_name) { |
152 EventRouter* router = EventRouter::Get(browser_context_); | 194 if (!extension_system_) |
195 return; | |
196 | |
197 EventRouter* router = extension_system_->event_router(); | |
153 if (!router) | 198 if (!router) |
154 return; | 199 return; |
200 | |
155 router->RemoveLazyEventListener(event_name, extension_id); | 201 router->RemoveLazyEventListener(event_name, extension_id); |
156 } | 202 } |
157 | 203 |
158 void ExtensionMessageFilter::OnExtensionAddFilteredListener( | 204 void ExtensionMessageFilter::OnExtensionAddFilteredListener( |
159 const std::string& extension_id, | 205 const std::string& extension_id, |
160 const std::string& event_name, | 206 const std::string& event_name, |
161 const base::DictionaryValue& filter, | 207 const base::DictionaryValue& filter, |
162 bool lazy) { | 208 bool lazy) { |
163 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 209 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
164 if (!process) | 210 if (!process) |
165 return; | 211 return; |
166 EventRouter* router = EventRouter::Get(browser_context_); | 212 |
213 if (!extension_system_) | |
214 return; | |
215 | |
216 EventRouter* router = extension_system_->event_router(); | |
167 if (!router) | 217 if (!router) |
168 return; | 218 return; |
219 | |
169 router->AddFilteredEventListener( | 220 router->AddFilteredEventListener( |
170 event_name, process, extension_id, filter, lazy); | 221 event_name, process, extension_id, filter, lazy); |
171 } | 222 } |
172 | 223 |
173 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener( | 224 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener( |
174 const std::string& extension_id, | 225 const std::string& extension_id, |
175 const std::string& event_name, | 226 const std::string& event_name, |
176 const base::DictionaryValue& filter, | 227 const base::DictionaryValue& filter, |
177 bool lazy) { | 228 bool lazy) { |
178 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 229 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
not at google - send to devlin
2015/02/10 18:37:15
I wonder if this can actually fail given it's call
Bernhard Bauer
2015/02/10 19:02:34
Process shuts down between the time the message is
| |
179 if (!process) | 230 if (!process) |
180 return; | 231 return; |
181 EventRouter* router = EventRouter::Get(browser_context_); | 232 |
233 if (!extension_system_) | |
234 return; | |
235 | |
236 EventRouter* router = extension_system_->event_router(); | |
182 if (!router) | 237 if (!router) |
183 return; | 238 return; |
239 | |
184 router->RemoveFilteredEventListener( | 240 router->RemoveFilteredEventListener( |
185 event_name, process, extension_id, filter, lazy); | 241 event_name, process, extension_id, filter, lazy); |
186 } | 242 } |
187 | 243 |
188 void ExtensionMessageFilter::OnExtensionShouldSuspendAck( | 244 void ExtensionMessageFilter::OnExtensionShouldSuspendAck( |
189 const std::string& extension_id, int sequence_id) { | 245 const std::string& extension_id, int sequence_id) { |
190 ProcessManager::Get(browser_context_) | 246 if (!process_manager_) |
191 ->OnShouldSuspendAck(extension_id, sequence_id); | 247 return; |
248 | |
249 process_manager_->OnShouldSuspendAck(extension_id, sequence_id); | |
not at google - send to devlin
2015/02/10 18:37:14
could you write these like
if (process_manager_)
Bernhard Bauer
2015/02/10 19:02:34
Yeah... I removed the check completely, because if
| |
192 } | 250 } |
193 | 251 |
194 void ExtensionMessageFilter::OnExtensionSuspendAck( | 252 void ExtensionMessageFilter::OnExtensionSuspendAck( |
195 const std::string& extension_id) { | 253 const std::string& extension_id) { |
196 ProcessManager::Get(browser_context_)->OnSuspendAck(extension_id); | 254 if (!process_manager_) |
255 return; | |
256 | |
257 process_manager_->OnSuspendAck(extension_id); | |
197 } | 258 } |
198 | 259 |
199 void ExtensionMessageFilter::OnExtensionTransferBlobsAck( | 260 void ExtensionMessageFilter::OnExtensionTransferBlobsAck( |
200 const std::vector<std::string>& blob_uuids) { | 261 const std::vector<std::string>& blob_uuids) { |
201 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 262 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
202 if (!process) | 263 if (!process) |
203 return; | 264 return; |
265 | |
204 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids); | 266 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids); |
205 } | 267 } |
206 | 268 |
207 void ExtensionMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) { | |
208 static int next_unique_id = 0; | |
209 *unique_id = ++next_unique_id; | |
210 } | |
211 | |
212 void ExtensionMessageFilter::OnExtensionResumeRequests(int route_id) { | |
213 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute( | |
214 render_process_id_, route_id); | |
215 } | |
216 | |
217 void ExtensionMessageFilter::OnExtensionRequestForIOThread( | |
218 int routing_id, | |
219 const ExtensionHostMsg_Request_Params& params) { | |
220 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
221 ExtensionFunctionDispatcher::DispatchOnIOThread( | |
222 extension_info_map_.get(), | |
223 browser_context_, | |
224 render_process_id_, | |
225 weak_ptr_factory_.GetWeakPtr(), | |
226 routing_id, | |
227 params); | |
228 } | |
229 | |
230 } // namespace extensions | 269 } // namespace extensions |
OLD | NEW |