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) { |
| 105 // If we have been shut down already, return. |
| 106 if (!extension_system_) |
| 107 return true; |
| 108 |
69 bool handled = true; | 109 bool handled = true; |
70 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message) | 110 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message) |
71 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, | 111 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, |
72 OnExtensionAddListener) | 112 OnExtensionAddListener) |
73 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener, | 113 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener, |
74 OnExtensionRemoveListener) | 114 OnExtensionRemoveListener) |
75 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener, | 115 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener, |
76 OnExtensionAddLazyListener) | 116 OnExtensionAddLazyListener) |
77 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, | 117 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, |
78 OnExtensionRemoveLazyListener) | 118 OnExtensionRemoveLazyListener) |
79 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, | 119 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, |
80 OnExtensionAddFilteredListener) | 120 OnExtensionAddFilteredListener) |
81 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, | 121 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, |
82 OnExtensionRemoveFilteredListener) | 122 OnExtensionRemoveFilteredListener) |
83 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck, | 123 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck, |
84 OnExtensionShouldSuspendAck) | 124 OnExtensionShouldSuspendAck) |
85 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, | 125 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, |
86 OnExtensionSuspendAck) | 126 OnExtensionSuspendAck) |
87 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck, | 127 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck, |
88 OnExtensionTransferBlobsAck) | 128 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) | 129 IPC_MESSAGE_UNHANDLED(handled = false) |
96 IPC_END_MESSAGE_MAP() | 130 IPC_END_MESSAGE_MAP() |
97 return handled; | 131 return handled; |
98 } | 132 } |
99 | 133 |
100 void ExtensionMessageFilter::OnExtensionAddListener( | 134 void ExtensionMessageFilter::OnExtensionAddListener( |
101 const std::string& extension_id, | 135 const std::string& extension_id, |
102 const GURL& listener_url, | 136 const GURL& listener_url, |
103 const std::string& event_name) { | 137 const std::string& event_name) { |
104 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 138 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
105 if (!process) | 139 if (!process) |
106 return; | 140 return; |
107 EventRouter* router = EventRouter::Get(browser_context_); | 141 |
| 142 EventRouter* router = extension_system_->event_router(); |
108 if (!router) | 143 if (!router) |
109 return; | 144 return; |
110 | 145 |
111 if (crx_file::id_util::IdIsValid(extension_id)) { | 146 if (crx_file::id_util::IdIsValid(extension_id)) { |
112 router->AddEventListener(event_name, process, extension_id); | 147 router->AddEventListener(event_name, process, extension_id); |
113 } else if (listener_url.is_valid()) { | 148 } else if (listener_url.is_valid()) { |
114 router->AddEventListenerForURL(event_name, process, listener_url); | 149 router->AddEventListenerForURL(event_name, process, listener_url); |
115 } else { | 150 } else { |
116 NOTREACHED() << "Tried to add an event listener without a valid " | 151 NOTREACHED() << "Tried to add an event listener without a valid " |
117 << "extension ID nor listener URL"; | 152 << "extension ID nor listener URL"; |
118 } | 153 } |
119 } | 154 } |
120 | 155 |
121 void ExtensionMessageFilter::OnExtensionRemoveListener( | 156 void ExtensionMessageFilter::OnExtensionRemoveListener( |
122 const std::string& extension_id, | 157 const std::string& extension_id, |
123 const GURL& listener_url, | 158 const GURL& listener_url, |
124 const std::string& event_name) { | 159 const std::string& event_name) { |
125 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 160 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
126 if (!process) | 161 if (!process) |
127 return; | 162 return; |
128 EventRouter* router = EventRouter::Get(browser_context_); | 163 |
| 164 EventRouter* router = extension_system_->event_router(); |
129 if (!router) | 165 if (!router) |
130 return; | 166 return; |
131 | 167 |
132 if (crx_file::id_util::IdIsValid(extension_id)) { | 168 if (crx_file::id_util::IdIsValid(extension_id)) { |
133 router->RemoveEventListener(event_name, process, extension_id); | 169 router->RemoveEventListener(event_name, process, extension_id); |
134 } else if (listener_url.is_valid()) { | 170 } else if (listener_url.is_valid()) { |
135 router->RemoveEventListenerForURL(event_name, process, listener_url); | 171 router->RemoveEventListenerForURL(event_name, process, listener_url); |
136 } else { | 172 } else { |
137 NOTREACHED() << "Tried to remove an event listener without a valid " | 173 NOTREACHED() << "Tried to remove an event listener without a valid " |
138 << "extension ID nor listener URL"; | 174 << "extension ID nor listener URL"; |
139 } | 175 } |
140 } | 176 } |
141 | 177 |
142 void ExtensionMessageFilter::OnExtensionAddLazyListener( | 178 void ExtensionMessageFilter::OnExtensionAddLazyListener( |
143 const std::string& extension_id, const std::string& event_name) { | 179 const std::string& extension_id, const std::string& event_name) { |
144 EventRouter* router = EventRouter::Get(browser_context_); | 180 EventRouter* router = extension_system_->event_router(); |
145 if (!router) | 181 if (!router) |
146 return; | 182 return; |
| 183 |
147 router->AddLazyEventListener(event_name, extension_id); | 184 router->AddLazyEventListener(event_name, extension_id); |
148 } | 185 } |
149 | 186 |
150 void ExtensionMessageFilter::OnExtensionRemoveLazyListener( | 187 void ExtensionMessageFilter::OnExtensionRemoveLazyListener( |
151 const std::string& extension_id, const std::string& event_name) { | 188 const std::string& extension_id, const std::string& event_name) { |
152 EventRouter* router = EventRouter::Get(browser_context_); | 189 EventRouter* router = extension_system_->event_router(); |
153 if (!router) | 190 if (!router) |
154 return; | 191 return; |
| 192 |
155 router->RemoveLazyEventListener(event_name, extension_id); | 193 router->RemoveLazyEventListener(event_name, extension_id); |
156 } | 194 } |
157 | 195 |
158 void ExtensionMessageFilter::OnExtensionAddFilteredListener( | 196 void ExtensionMessageFilter::OnExtensionAddFilteredListener( |
159 const std::string& extension_id, | 197 const std::string& extension_id, |
160 const std::string& event_name, | 198 const std::string& event_name, |
161 const base::DictionaryValue& filter, | 199 const base::DictionaryValue& filter, |
162 bool lazy) { | 200 bool lazy) { |
163 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 201 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
164 if (!process) | 202 if (!process) |
165 return; | 203 return; |
166 EventRouter* router = EventRouter::Get(browser_context_); | 204 |
| 205 EventRouter* router = extension_system_->event_router(); |
167 if (!router) | 206 if (!router) |
168 return; | 207 return; |
| 208 |
169 router->AddFilteredEventListener( | 209 router->AddFilteredEventListener( |
170 event_name, process, extension_id, filter, lazy); | 210 event_name, process, extension_id, filter, lazy); |
171 } | 211 } |
172 | 212 |
173 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener( | 213 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener( |
174 const std::string& extension_id, | 214 const std::string& extension_id, |
175 const std::string& event_name, | 215 const std::string& event_name, |
176 const base::DictionaryValue& filter, | 216 const base::DictionaryValue& filter, |
177 bool lazy) { | 217 bool lazy) { |
178 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 218 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
179 if (!process) | 219 if (!process) |
180 return; | 220 return; |
181 EventRouter* router = EventRouter::Get(browser_context_); | 221 |
| 222 EventRouter* router = extension_system_->event_router(); |
182 if (!router) | 223 if (!router) |
183 return; | 224 return; |
| 225 |
184 router->RemoveFilteredEventListener( | 226 router->RemoveFilteredEventListener( |
185 event_name, process, extension_id, filter, lazy); | 227 event_name, process, extension_id, filter, lazy); |
186 } | 228 } |
187 | 229 |
188 void ExtensionMessageFilter::OnExtensionShouldSuspendAck( | 230 void ExtensionMessageFilter::OnExtensionShouldSuspendAck( |
189 const std::string& extension_id, int sequence_id) { | 231 const std::string& extension_id, int sequence_id) { |
190 ProcessManager::Get(browser_context_) | 232 process_manager_->OnShouldSuspendAck(extension_id, sequence_id); |
191 ->OnShouldSuspendAck(extension_id, sequence_id); | |
192 } | 233 } |
193 | 234 |
194 void ExtensionMessageFilter::OnExtensionSuspendAck( | 235 void ExtensionMessageFilter::OnExtensionSuspendAck( |
195 const std::string& extension_id) { | 236 const std::string& extension_id) { |
196 ProcessManager::Get(browser_context_)->OnSuspendAck(extension_id); | 237 process_manager_->OnSuspendAck(extension_id); |
197 } | 238 } |
198 | 239 |
199 void ExtensionMessageFilter::OnExtensionTransferBlobsAck( | 240 void ExtensionMessageFilter::OnExtensionTransferBlobsAck( |
200 const std::vector<std::string>& blob_uuids) { | 241 const std::vector<std::string>& blob_uuids) { |
201 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); | 242 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_); |
202 if (!process) | 243 if (!process) |
203 return; | 244 return; |
| 245 |
204 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids); | 246 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids); |
205 } | 247 } |
206 | 248 |
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 | 249 } // namespace extensions |
OLD | NEW |