[Smart Lock] Record a detailed UMA metric for each unlock attempt by Smart Lock users.
[chromium-blink-merge.git] / extensions / browser / extension_message_filter.cc
blob2a67822685898ccc57bbb6af5f11fca7ac930f1c
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 "base/memory/singleton.h"
8 #include "components/crx_file/id_util.h"
9 #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "extensions/browser/blob_holder.h"
13 #include "extensions/browser/event_router.h"
14 #include "extensions/browser/extension_system.h"
15 #include "extensions/browser/extension_system_provider.h"
16 #include "extensions/browser/extensions_browser_client.h"
17 #include "extensions/browser/process_manager.h"
18 #include "extensions/browser/process_manager_factory.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 namespace {
30 class ShutdownNotifierFactory
31 : public BrowserContextKeyedServiceShutdownNotifierFactory {
32 public:
33 static ShutdownNotifierFactory* GetInstance() {
34 return Singleton<ShutdownNotifierFactory>::get();
37 private:
38 friend struct DefaultSingletonTraits<ShutdownNotifierFactory>;
40 ShutdownNotifierFactory()
41 : BrowserContextKeyedServiceShutdownNotifierFactory(
42 "ExtensionMessageFilter") {
43 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
44 DependsOn(ProcessManagerFactory::GetInstance());
46 ~ShutdownNotifierFactory() override {}
48 DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory);
51 } // namespace
53 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id,
54 content::BrowserContext* context)
55 : BrowserMessageFilter(ExtensionMsgStart),
56 render_process_id_(render_process_id),
57 extension_system_(ExtensionSystem::Get(context)),
58 process_manager_(ProcessManager::Get(context)) {
59 DCHECK_CURRENTLY_ON(BrowserThread::UI);
60 shutdown_notifier_ =
61 ShutdownNotifierFactory::GetInstance()->Get(context)->Subscribe(
62 base::Bind(&ExtensionMessageFilter::ShutdownOnUIThread,
63 base::Unretained(this)));
66 void ExtensionMessageFilter::EnsureShutdownNotifierFactoryBuilt() {
67 ShutdownNotifierFactory::GetInstance();
70 ExtensionMessageFilter::~ExtensionMessageFilter() {
71 DCHECK_CURRENTLY_ON(BrowserThread::UI);
74 void ExtensionMessageFilter::ShutdownOnUIThread() {
75 extension_system_ = nullptr;
76 process_manager_ = nullptr;
77 shutdown_notifier_.reset();
80 void ExtensionMessageFilter::OverrideThreadForMessage(
81 const IPC::Message& message,
82 BrowserThread::ID* thread) {
83 switch (message.type()) {
84 case ExtensionHostMsg_AddListener::ID:
85 case ExtensionHostMsg_RemoveListener::ID:
86 case ExtensionHostMsg_AddLazyListener::ID:
87 case ExtensionHostMsg_RemoveLazyListener::ID:
88 case ExtensionHostMsg_AddFilteredListener::ID:
89 case ExtensionHostMsg_RemoveFilteredListener::ID:
90 case ExtensionHostMsg_ShouldSuspendAck::ID:
91 case ExtensionHostMsg_SuspendAck::ID:
92 case ExtensionHostMsg_TransferBlobsAck::ID:
93 *thread = BrowserThread::UI;
94 break;
95 default:
96 break;
100 void ExtensionMessageFilter::OnDestruct() const {
101 BrowserThread::DeleteOnUIThread::Destruct(this);
104 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) {
105 // If we have been shut down already, return.
106 if (!extension_system_)
107 return true;
109 bool handled = true;
110 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message)
111 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener,
112 OnExtensionAddListener)
113 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener,
114 OnExtensionRemoveListener)
115 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener,
116 OnExtensionAddLazyListener)
117 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener,
118 OnExtensionRemoveLazyListener)
119 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener,
120 OnExtensionAddFilteredListener)
121 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener,
122 OnExtensionRemoveFilteredListener)
123 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck,
124 OnExtensionShouldSuspendAck)
125 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck,
126 OnExtensionSuspendAck)
127 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck,
128 OnExtensionTransferBlobsAck)
129 IPC_MESSAGE_UNHANDLED(handled = false)
130 IPC_END_MESSAGE_MAP()
131 return handled;
134 void ExtensionMessageFilter::OnExtensionAddListener(
135 const std::string& extension_id,
136 const GURL& listener_url,
137 const std::string& event_name) {
138 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
139 if (!process)
140 return;
142 EventRouter* router = extension_system_->event_router();
143 if (!router)
144 return;
146 if (crx_file::id_util::IdIsValid(extension_id)) {
147 router->AddEventListener(event_name, process, extension_id);
148 } else if (listener_url.is_valid()) {
149 router->AddEventListenerForURL(event_name, process, listener_url);
150 } else {
151 NOTREACHED() << "Tried to add an event listener without a valid "
152 << "extension ID nor listener URL";
156 void ExtensionMessageFilter::OnExtensionRemoveListener(
157 const std::string& extension_id,
158 const GURL& listener_url,
159 const std::string& event_name) {
160 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
161 if (!process)
162 return;
164 EventRouter* router = extension_system_->event_router();
165 if (!router)
166 return;
168 if (crx_file::id_util::IdIsValid(extension_id)) {
169 router->RemoveEventListener(event_name, process, extension_id);
170 } else if (listener_url.is_valid()) {
171 router->RemoveEventListenerForURL(event_name, process, listener_url);
172 } else {
173 NOTREACHED() << "Tried to remove an event listener without a valid "
174 << "extension ID nor listener URL";
178 void ExtensionMessageFilter::OnExtensionAddLazyListener(
179 const std::string& extension_id, const std::string& event_name) {
180 EventRouter* router = extension_system_->event_router();
181 if (!router)
182 return;
184 router->AddLazyEventListener(event_name, extension_id);
187 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
188 const std::string& extension_id, const std::string& event_name) {
189 EventRouter* router = extension_system_->event_router();
190 if (!router)
191 return;
193 router->RemoveLazyEventListener(event_name, extension_id);
196 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
197 const std::string& extension_id,
198 const std::string& event_name,
199 const base::DictionaryValue& filter,
200 bool lazy) {
201 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
202 if (!process)
203 return;
205 EventRouter* router = extension_system_->event_router();
206 if (!router)
207 return;
209 router->AddFilteredEventListener(
210 event_name, process, extension_id, filter, lazy);
213 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
214 const std::string& extension_id,
215 const std::string& event_name,
216 const base::DictionaryValue& filter,
217 bool lazy) {
218 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
219 if (!process)
220 return;
222 EventRouter* router = extension_system_->event_router();
223 if (!router)
224 return;
226 router->RemoveFilteredEventListener(
227 event_name, process, extension_id, filter, lazy);
230 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
231 const std::string& extension_id, int sequence_id) {
232 process_manager_->OnShouldSuspendAck(extension_id, sequence_id);
235 void ExtensionMessageFilter::OnExtensionSuspendAck(
236 const std::string& extension_id) {
237 process_manager_->OnSuspendAck(extension_id);
240 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
241 const std::vector<std::string>& blob_uuids) {
242 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
243 if (!process)
244 return;
246 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids);
249 } // namespace extensions