Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(592)

Side by Side Diff: extensions/browser/extension_message_filter.cc

Issue 901573003: Split ExtensionMessageFilter up into a UI thread part and an IO thread part. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698