Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / extension_message_filter.cc
blob053d8eed1890fc7edb012a72fadc2429f11bff4e
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/event_router_factory.h"
15 #include "extensions/browser/process_manager.h"
16 #include "extensions/browser/process_manager_factory.h"
17 #include "extensions/common/extension.h"
18 #include "extensions/common/extension_messages.h"
19 #include "ipc/ipc_message_macros.h"
21 using content::BrowserThread;
22 using content::RenderProcessHost;
24 namespace extensions {
26 namespace {
28 class ShutdownNotifierFactory
29 : public BrowserContextKeyedServiceShutdownNotifierFactory {
30 public:
31 static ShutdownNotifierFactory* GetInstance() {
32 return Singleton<ShutdownNotifierFactory>::get();
35 private:
36 friend struct DefaultSingletonTraits<ShutdownNotifierFactory>;
38 ShutdownNotifierFactory()
39 : BrowserContextKeyedServiceShutdownNotifierFactory(
40 "ExtensionMessageFilter") {
41 DependsOn(EventRouterFactory::GetInstance());
42 DependsOn(ProcessManagerFactory::GetInstance());
44 ~ShutdownNotifierFactory() override {}
46 DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory);
49 } // namespace
51 ExtensionMessageFilter::ExtensionMessageFilter(int render_process_id,
52 content::BrowserContext* context)
53 : BrowserMessageFilter(ExtensionMsgStart),
54 render_process_id_(render_process_id),
55 event_router_(EventRouter::Get(context)),
56 process_manager_(ProcessManager::Get(context)) {
57 DCHECK_CURRENTLY_ON(BrowserThread::UI);
58 shutdown_notifier_ =
59 ShutdownNotifierFactory::GetInstance()->Get(context)->Subscribe(
60 base::Bind(&ExtensionMessageFilter::ShutdownOnUIThread,
61 base::Unretained(this)));
64 void ExtensionMessageFilter::EnsureShutdownNotifierFactoryBuilt() {
65 ShutdownNotifierFactory::GetInstance();
68 ExtensionMessageFilter::~ExtensionMessageFilter() {
69 DCHECK_CURRENTLY_ON(BrowserThread::UI);
72 void ExtensionMessageFilter::ShutdownOnUIThread() {
73 event_router_ = nullptr;
74 process_manager_ = nullptr;
75 shutdown_notifier_.reset();
78 void ExtensionMessageFilter::OverrideThreadForMessage(
79 const IPC::Message& message,
80 BrowserThread::ID* thread) {
81 switch (message.type()) {
82 case ExtensionHostMsg_AddListener::ID:
83 case ExtensionHostMsg_RemoveListener::ID:
84 case ExtensionHostMsg_AddLazyListener::ID:
85 case ExtensionHostMsg_RemoveLazyListener::ID:
86 case ExtensionHostMsg_AddFilteredListener::ID:
87 case ExtensionHostMsg_RemoveFilteredListener::ID:
88 case ExtensionHostMsg_ShouldSuspendAck::ID:
89 case ExtensionHostMsg_SuspendAck::ID:
90 case ExtensionHostMsg_TransferBlobsAck::ID:
91 *thread = BrowserThread::UI;
92 break;
93 default:
94 break;
98 void ExtensionMessageFilter::OnDestruct() const {
99 BrowserThread::DeleteOnUIThread::Destruct(this);
102 bool ExtensionMessageFilter::OnMessageReceived(const IPC::Message& message) {
103 // If we have been shut down already, return.
104 if (!event_router_)
105 return true;
107 bool handled = true;
108 IPC_BEGIN_MESSAGE_MAP(ExtensionMessageFilter, message)
109 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener,
110 OnExtensionAddListener)
111 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener,
112 OnExtensionRemoveListener)
113 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener,
114 OnExtensionAddLazyListener)
115 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener,
116 OnExtensionRemoveLazyListener)
117 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener,
118 OnExtensionAddFilteredListener)
119 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener,
120 OnExtensionRemoveFilteredListener)
121 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck,
122 OnExtensionShouldSuspendAck)
123 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck,
124 OnExtensionSuspendAck)
125 IPC_MESSAGE_HANDLER(ExtensionHostMsg_TransferBlobsAck,
126 OnExtensionTransferBlobsAck)
127 IPC_MESSAGE_UNHANDLED(handled = false)
128 IPC_END_MESSAGE_MAP()
129 return handled;
132 void ExtensionMessageFilter::OnExtensionAddListener(
133 const std::string& extension_id,
134 const GURL& listener_url,
135 const std::string& event_name) {
136 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
137 if (!process)
138 return;
140 if (!event_router_)
141 return;
143 if (crx_file::id_util::IdIsValid(extension_id)) {
144 event_router_->AddEventListener(event_name, process, extension_id);
145 } else if (listener_url.is_valid()) {
146 event_router_->AddEventListenerForURL(event_name, process, listener_url);
147 } else {
148 NOTREACHED() << "Tried to add an event listener without a valid "
149 << "extension ID nor listener URL";
153 void ExtensionMessageFilter::OnExtensionRemoveListener(
154 const std::string& extension_id,
155 const GURL& listener_url,
156 const std::string& event_name) {
157 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
158 if (!process)
159 return;
161 if (!event_router_)
162 return;
164 if (crx_file::id_util::IdIsValid(extension_id)) {
165 event_router_->RemoveEventListener(event_name, process, extension_id);
166 } else if (listener_url.is_valid()) {
167 event_router_->RemoveEventListenerForURL(event_name, process, listener_url);
168 } else {
169 NOTREACHED() << "Tried to remove an event listener without a valid "
170 << "extension ID nor listener URL";
174 void ExtensionMessageFilter::OnExtensionAddLazyListener(
175 const std::string& extension_id, const std::string& event_name) {
176 if (!event_router_)
177 return;
179 event_router_->AddLazyEventListener(event_name, extension_id);
182 void ExtensionMessageFilter::OnExtensionRemoveLazyListener(
183 const std::string& extension_id, const std::string& event_name) {
184 if (!event_router_)
185 return;
187 event_router_->RemoveLazyEventListener(event_name, extension_id);
190 void ExtensionMessageFilter::OnExtensionAddFilteredListener(
191 const std::string& extension_id,
192 const std::string& event_name,
193 const base::DictionaryValue& filter,
194 bool lazy) {
195 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
196 if (!process)
197 return;
199 if (!event_router_)
200 return;
202 event_router_->AddFilteredEventListener(event_name, process, extension_id,
203 filter, lazy);
206 void ExtensionMessageFilter::OnExtensionRemoveFilteredListener(
207 const std::string& extension_id,
208 const std::string& event_name,
209 const base::DictionaryValue& filter,
210 bool lazy) {
211 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
212 if (!process)
213 return;
215 if (!event_router_)
216 return;
218 event_router_->RemoveFilteredEventListener(event_name, process, extension_id,
219 filter, lazy);
222 void ExtensionMessageFilter::OnExtensionShouldSuspendAck(
223 const std::string& extension_id, int sequence_id) {
224 process_manager_->OnShouldSuspendAck(extension_id, sequence_id);
227 void ExtensionMessageFilter::OnExtensionSuspendAck(
228 const std::string& extension_id) {
229 process_manager_->OnSuspendAck(extension_id);
232 void ExtensionMessageFilter::OnExtensionTransferBlobsAck(
233 const std::vector<std::string>& blob_uuids) {
234 RenderProcessHost* process = RenderProcessHost::FromID(render_process_id_);
235 if (!process)
236 return;
238 BlobHolder::FromRenderProcessHost(process)->DropBlobs(blob_uuids);
241 } // namespace extensions