| 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 |