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

Side by Side Diff: content/browser/service_worker/embedded_worker_instance.cc

Issue 796393005: Cleanup: Remove if (!CurrentlyOn()) PostTask() pattern in EmbeddedWorkerInstance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « content/browser/service_worker/embedded_worker_instance.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/browser/service_worker/embedded_worker_instance.h" 5 #include "content/browser/service_worker/embedded_worker_instance.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/threading/non_thread_safe.h"
12 #include "content/browser/devtools/service_worker_devtools_manager.h" 13 #include "content/browser/devtools/service_worker_devtools_manager.h"
13 #include "content/browser/service_worker/embedded_worker_registry.h" 14 #include "content/browser/service_worker/embedded_worker_registry.h"
14 #include "content/browser/service_worker/service_worker_context_core.h" 15 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/common/service_worker/embedded_worker_messages.h" 16 #include "content/common/service_worker/embedded_worker_messages.h"
16 #include "content/common/service_worker/service_worker_types.h" 17 #include "content/common/service_worker/service_worker_types.h"
17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/render_process_host.h" 19 #include "content/public/browser/render_process_host.h"
19 #include "ipc/ipc_message.h" 20 #include "ipc/ipc_message.h"
20 #include "url/gurl.h" 21 #include "url/gurl.h"
21 22
22 namespace content { 23 namespace content {
23 24
24 namespace { 25 namespace {
25 26
26 // Functor to sort by the .second element of a struct. 27 // Functor to sort by the .second element of a struct.
27 struct SecondGreater { 28 struct SecondGreater {
28 template <typename Value> 29 template <typename Value>
29 bool operator()(const Value& lhs, const Value& rhs) { 30 bool operator()(const Value& lhs, const Value& rhs) {
30 return lhs.second > rhs.second; 31 return lhs.second > rhs.second;
31 } 32 }
32 }; 33 };
33 34
34 void NotifyWorkerReadyForInspection(int worker_process_id, 35 void NotifyWorkerReadyForInspectionOnUI(int worker_process_id,
35 int worker_route_id) { 36 int worker_route_id) {
36 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
38 BrowserThread::PostTask(BrowserThread::UI,
39 FROM_HERE,
40 base::Bind(NotifyWorkerReadyForInspection,
41 worker_process_id,
42 worker_route_id));
43 return;
44 }
45 ServiceWorkerDevToolsManager::GetInstance()->WorkerReadyForInspection( 38 ServiceWorkerDevToolsManager::GetInstance()->WorkerReadyForInspection(
46 worker_process_id, worker_route_id); 39 worker_process_id, worker_route_id);
47 } 40 }
48 41
49 void NotifyWorkerDestroyed(int worker_process_id, int worker_route_id) { 42 void NotifyWorkerDestroyedOnUI(int worker_process_id, int worker_route_id) {
50 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
52 BrowserThread::PostTask(
53 BrowserThread::UI,
54 FROM_HERE,
55 base::Bind(NotifyWorkerDestroyed, worker_process_id, worker_route_id));
56 return;
57 }
58 ServiceWorkerDevToolsManager::GetInstance()->WorkerDestroyed( 44 ServiceWorkerDevToolsManager::GetInstance()->WorkerDestroyed(
59 worker_process_id, worker_route_id); 45 worker_process_id, worker_route_id);
60 } 46 }
61 47
62 void NotifyWorkerStopIgnored(int worker_process_id, int worker_route_id) { 48 void NotifyWorkerStopIgnoredOnUI(int worker_process_id, int worker_route_id) {
63 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
65 BrowserThread::PostTask(BrowserThread::UI,
66 FROM_HERE,
67 base::Bind(NotifyWorkerStopIgnored,
68 worker_process_id,
69 worker_route_id));
70 return;
71 }
72 ServiceWorkerDevToolsManager::GetInstance()->WorkerStopIgnored( 50 ServiceWorkerDevToolsManager::GetInstance()->WorkerStopIgnored(
73 worker_process_id, worker_route_id); 51 worker_process_id, worker_route_id);
74 } 52 }
75 53
76 54 void RegisterToWorkerDevToolsManagerOnUI(
77 void RegisterToWorkerDevToolsManager(
78 int process_id, 55 int process_id,
79 const ServiceWorkerContextCore* service_worker_context, 56 const ServiceWorkerContextCore* service_worker_context,
80 base::WeakPtr<ServiceWorkerContextCore> service_worker_context_weak, 57 const base::WeakPtr<ServiceWorkerContextCore>& service_worker_context_weak,
81 int64 service_worker_version_id, 58 int64 service_worker_version_id,
82 const GURL& url, 59 const GURL& url,
83 const base::Callback<void(int worker_devtools_agent_route_id, 60 const base::Callback<void(int worker_devtools_agent_route_id,
84 bool wait_for_debugger)>& callback) { 61 bool wait_for_debugger)>& callback) {
85 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
87 BrowserThread::PostTask(BrowserThread::UI,
88 FROM_HERE,
89 base::Bind(RegisterToWorkerDevToolsManager,
90 process_id,
91 service_worker_context,
92 service_worker_context_weak,
93 service_worker_version_id,
94 url,
95 callback));
96 return;
97 }
98 int worker_devtools_agent_route_id = MSG_ROUTING_NONE; 63 int worker_devtools_agent_route_id = MSG_ROUTING_NONE;
99 bool wait_for_debugger = false; 64 bool wait_for_debugger = false;
100 if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) { 65 if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) {
101 // |rph| may be NULL in unit tests. 66 // |rph| may be NULL in unit tests.
102 worker_devtools_agent_route_id = rph->GetNextRoutingID(); 67 worker_devtools_agent_route_id = rph->GetNextRoutingID();
103 wait_for_debugger = 68 wait_for_debugger =
104 ServiceWorkerDevToolsManager::GetInstance()->WorkerCreated( 69 ServiceWorkerDevToolsManager::GetInstance()->WorkerCreated(
105 process_id, 70 process_id,
106 worker_devtools_agent_route_id, 71 worker_devtools_agent_route_id,
107 ServiceWorkerDevToolsManager::ServiceWorkerIdentifier( 72 ServiceWorkerDevToolsManager::ServiceWorkerIdentifier(
108 service_worker_context, 73 service_worker_context,
109 service_worker_context_weak, 74 service_worker_context_weak,
110 service_worker_version_id, 75 service_worker_version_id,
111 url)); 76 url));
112 } 77 }
113 BrowserThread::PostTask( 78 BrowserThread::PostTask(
114 BrowserThread::IO, 79 BrowserThread::IO,
115 FROM_HERE, 80 FROM_HERE,
116 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger)); 81 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger));
117 } 82 }
118 83
119 } // namespace 84 } // namespace
120 85
86 // Lives on IO thread, proxies notifications to DevToolsManager that lives on
87 // UI thread. Owned by EmbeddedWorkerInstance.
88 class EmbeddedWorkerInstance::DevToolsProxy : public base::NonThreadSafe {
89 public:
90 DevToolsProxy(int process_id, int agent_route_id)
91 : process_id_(process_id),
92 agent_route_id_(agent_route_id) {}
93
94 ~DevToolsProxy() {
95 BrowserThread::PostTask(
96 BrowserThread::UI,
97 FROM_HERE,
98 base::Bind(NotifyWorkerDestroyedOnUI,
99 process_id_, agent_route_id_));
100 }
101
102 void NotifyWorkerReadyForInspection() {
103 DCHECK(CalledOnValidThread());
104 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
105 base::Bind(NotifyWorkerReadyForInspectionOnUI,
106 process_id_, agent_route_id_));
107 }
108
109 void NotifyWorkerStopIgnored() {
110 DCHECK(CalledOnValidThread());
111 BrowserThread::PostTask(BrowserThread::UI,
112 FROM_HERE,
113 base::Bind(NotifyWorkerStopIgnoredOnUI,
114 process_id_, agent_route_id_));
115 }
116
117 int agent_route_id() const { return agent_route_id_; }
118
119 private:
120 const int process_id_;
121 const int agent_route_id_;
122 DISALLOW_COPY_AND_ASSIGN(DevToolsProxy);
123 };
124
121 EmbeddedWorkerInstance::~EmbeddedWorkerInstance() { 125 EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
122 if (status_ == STARTING || status_ == RUNNING) 126 if (status_ == STARTING || status_ == RUNNING)
123 Stop(); 127 Stop();
124 if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE) 128 devtools_proxy_.reset();
125 NotifyWorkerDestroyed(process_id_, worker_devtools_agent_route_id_);
126 if (context_ && process_id_ != -1) 129 if (context_ && process_id_ != -1)
127 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_); 130 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
128 registry_->RemoveWorker(process_id_, embedded_worker_id_); 131 registry_->RemoveWorker(process_id_, embedded_worker_id_);
129 } 132 }
130 133
131 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id, 134 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
132 const GURL& scope, 135 const GURL& scope,
133 const GURL& script_url, 136 const GURL& script_url,
134 bool pause_after_download, 137 bool pause_after_download,
135 const StatusCallback& callback) { 138 const StatusCallback& callback) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 DCHECK(status_ == STARTING || status_ == RUNNING); 171 DCHECK(status_ == STARTING || status_ == RUNNING);
169 ServiceWorkerStatusCode status = 172 ServiceWorkerStatusCode status =
170 registry_->StopWorker(process_id_, embedded_worker_id_); 173 registry_->StopWorker(process_id_, embedded_worker_id_);
171 if (status == SERVICE_WORKER_OK) 174 if (status == SERVICE_WORKER_OK)
172 status_ = STOPPING; 175 status_ = STOPPING;
173 return status; 176 return status;
174 } 177 }
175 178
176 void EmbeddedWorkerInstance::StopIfIdle() { 179 void EmbeddedWorkerInstance::StopIfIdle() {
177 if (devtools_attached_) { 180 if (devtools_attached_) {
178 NotifyWorkerStopIgnored(process_id_, worker_devtools_agent_route_id_); 181 if (devtools_proxy_)
182 devtools_proxy_->NotifyWorkerStopIgnored();
179 return; 183 return;
180 } 184 }
181 Stop(); 185 Stop();
182 } 186 }
183 187
184 void EmbeddedWorkerInstance::ResumeAfterDownload() { 188 void EmbeddedWorkerInstance::ResumeAfterDownload() {
185 DCHECK_EQ(STARTING, status_); 189 DCHECK_EQ(STARTING, status_);
186 registry_->Send( 190 registry_->Send(
187 process_id_, 191 process_id_,
188 new EmbeddedWorkerMsg_ResumeAfterDownload(embedded_worker_id_)); 192 new EmbeddedWorkerMsg_ResumeAfterDownload(embedded_worker_id_));
(...skipping 11 matching lines...) Expand all
200 204
201 EmbeddedWorkerInstance::EmbeddedWorkerInstance( 205 EmbeddedWorkerInstance::EmbeddedWorkerInstance(
202 base::WeakPtr<ServiceWorkerContextCore> context, 206 base::WeakPtr<ServiceWorkerContextCore> context,
203 int embedded_worker_id) 207 int embedded_worker_id)
204 : context_(context), 208 : context_(context),
205 registry_(context->embedded_worker_registry()), 209 registry_(context->embedded_worker_registry()),
206 embedded_worker_id_(embedded_worker_id), 210 embedded_worker_id_(embedded_worker_id),
207 status_(STOPPED), 211 status_(STOPPED),
208 process_id_(-1), 212 process_id_(-1),
209 thread_id_(kInvalidEmbeddedWorkerThreadId), 213 thread_id_(kInvalidEmbeddedWorkerThreadId),
210 worker_devtools_agent_route_id_(MSG_ROUTING_NONE),
211 devtools_attached_(false), 214 devtools_attached_(false),
212 weak_factory_(this) { 215 weak_factory_(this) {
213 } 216 }
214 217
215 // static 218 // static
216 void EmbeddedWorkerInstance::RunProcessAllocated( 219 void EmbeddedWorkerInstance::RunProcessAllocated(
217 base::WeakPtr<EmbeddedWorkerInstance> instance, 220 base::WeakPtr<EmbeddedWorkerInstance> instance,
218 base::WeakPtr<ServiceWorkerContextCore> context, 221 base::WeakPtr<ServiceWorkerContextCore> context,
219 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, 222 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
220 const EmbeddedWorkerInstance::StatusCallback& callback, 223 const EmbeddedWorkerInstance::StatusCallback& callback,
(...skipping 26 matching lines...) Expand all
247 params.get(), 250 params.get(),
248 "Status", status); 251 "Status", status);
249 if (status != SERVICE_WORKER_OK) { 252 if (status != SERVICE_WORKER_OK) {
250 status_ = STOPPED; 253 status_ = STOPPED;
251 callback.Run(status); 254 callback.Run(status);
252 return; 255 return;
253 } 256 }
254 const int64 service_worker_version_id = params->service_worker_version_id; 257 const int64 service_worker_version_id = params->service_worker_version_id;
255 process_id_ = process_id; 258 process_id_ = process_id;
256 GURL script_url(params->script_url); 259 GURL script_url(params->script_url);
257 RegisterToWorkerDevToolsManager( 260
258 process_id, 261 // Register this worker to DevToolsManager on UI thread, then continue to
259 context_.get(), 262 // call SendStartWorker on IO thread.
260 context_, 263 BrowserThread::PostTask(
261 service_worker_version_id, 264 BrowserThread::UI,
262 script_url, 265 FROM_HERE,
263 base::Bind(&EmbeddedWorkerInstance::SendStartWorker, 266 base::Bind(RegisterToWorkerDevToolsManagerOnUI,
264 weak_factory_.GetWeakPtr(), 267 process_id_,
265 base::Passed(&params), 268 context_.get(),
266 callback)); 269 context_,
270 service_worker_version_id,
271 script_url,
272 base::Bind(&EmbeddedWorkerInstance::SendStartWorker,
273 weak_factory_.GetWeakPtr(),
274 base::Passed(&params),
275 callback)));
267 } 276 }
268 277
269 void EmbeddedWorkerInstance::SendStartWorker( 278 void EmbeddedWorkerInstance::SendStartWorker(
270 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, 279 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
271 const StatusCallback& callback, 280 const StatusCallback& callback,
272 int worker_devtools_agent_route_id, 281 int worker_devtools_agent_route_id,
273 bool wait_for_debugger) { 282 bool wait_for_debugger) {
274 worker_devtools_agent_route_id_ = worker_devtools_agent_route_id; 283 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) {
284 DCHECK(!devtools_proxy_);
285 devtools_proxy_.reset(new DevToolsProxy(process_id_,
286 worker_devtools_agent_route_id));
287 }
275 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; 288 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
276 params->wait_for_debugger = wait_for_debugger; 289 params->wait_for_debugger = wait_for_debugger;
277 ServiceWorkerStatusCode status = 290 ServiceWorkerStatusCode status =
278 registry_->SendStartWorker(params.Pass(), process_id_); 291 registry_->SendStartWorker(params.Pass(), process_id_);
279 if (status != SERVICE_WORKER_OK) { 292 if (status != SERVICE_WORKER_OK) {
280 callback.Run(status); 293 callback.Run(status);
281 return; 294 return;
282 } 295 }
283 DCHECK(start_callback_.is_null()); 296 DCHECK(start_callback_.is_null());
284 start_callback_ = callback; 297 start_callback_ = callback;
285 } 298 }
286 299
287 void EmbeddedWorkerInstance::OnReadyForInspection() { 300 void EmbeddedWorkerInstance::OnReadyForInspection() {
288 if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE) 301 if (devtools_proxy_)
289 NotifyWorkerReadyForInspection(process_id_, 302 devtools_proxy_->NotifyWorkerReadyForInspection();
290 worker_devtools_agent_route_id_);
291 } 303 }
292 304
293 void EmbeddedWorkerInstance::OnScriptLoaded(int thread_id) { 305 void EmbeddedWorkerInstance::OnScriptLoaded(int thread_id) {
294 thread_id_ = thread_id; 306 thread_id_ = thread_id;
295 } 307 }
296 308
297 void EmbeddedWorkerInstance::OnScriptLoadFailed() { 309 void EmbeddedWorkerInstance::OnScriptLoadFailed() {
298 } 310 }
299 311
300 void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) { 312 void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) {
301 DCHECK(!start_callback_.is_null()); 313 DCHECK(!start_callback_.is_null());
302 start_callback_.Run(success ? SERVICE_WORKER_OK 314 start_callback_.Run(success ? SERVICE_WORKER_OK
303 : SERVICE_WORKER_ERROR_START_WORKER_FAILED); 315 : SERVICE_WORKER_ERROR_START_WORKER_FAILED);
304 start_callback_.Reset(); 316 start_callback_.Reset();
305 } 317 }
306 318
307 void EmbeddedWorkerInstance::OnStarted() { 319 void EmbeddedWorkerInstance::OnStarted() {
308 // Stop is requested before OnStarted is sent back from the worker. 320 // Stop is requested before OnStarted is sent back from the worker.
309 if (status_ == STOPPING) 321 if (status_ == STOPPING)
310 return; 322 return;
311 DCHECK(status_ == STARTING); 323 DCHECK(status_ == STARTING);
312 status_ = RUNNING; 324 status_ = RUNNING;
313 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted()); 325 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted());
314 } 326 }
315 327
316 void EmbeddedWorkerInstance::OnStopped() { 328 void EmbeddedWorkerInstance::OnStopped() {
317 if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE) 329 devtools_proxy_.reset();
318 NotifyWorkerDestroyed(process_id_, worker_devtools_agent_route_id_);
319 if (context_) 330 if (context_)
320 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_); 331 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
321 Status old_status = status_; 332 Status old_status = status_;
322 status_ = STOPPED; 333 status_ = STOPPED;
323 process_id_ = -1; 334 process_id_ = -1;
324 thread_id_ = -1; 335 thread_id_ = -1;
325 worker_devtools_agent_route_id_ = MSG_ROUTING_NONE;
326 start_callback_.Reset(); 336 start_callback_.Reset();
327 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(old_status)); 337 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(old_status));
328 } 338 }
329 339
330 void EmbeddedWorkerInstance::OnPausedAfterDownload() { 340 void EmbeddedWorkerInstance::OnPausedAfterDownload() {
331 // Stop can be requested before getting this far. 341 // Stop can be requested before getting this far.
332 if (status_ == STOPPING) 342 if (status_ == STOPPING)
333 return; 343 return;
334 DCHECK(status_ == STARTING); 344 DCHECK(status_ == STARTING);
335 FOR_EACH_OBSERVER(Listener, listener_list_, OnPausedAfterDownload()); 345 FOR_EACH_OBSERVER(Listener, listener_list_, OnPausedAfterDownload());
(...skipping 25 matching lines...) Expand all
361 const base::string16& message, 371 const base::string16& message,
362 int line_number, 372 int line_number,
363 const GURL& source_url) { 373 const GURL& source_url) {
364 FOR_EACH_OBSERVER( 374 FOR_EACH_OBSERVER(
365 Listener, 375 Listener,
366 listener_list_, 376 listener_list_,
367 OnReportConsoleMessage( 377 OnReportConsoleMessage(
368 source_identifier, message_level, message, line_number, source_url)); 378 source_identifier, message_level, message, line_number, source_url));
369 } 379 }
370 380
381 int EmbeddedWorkerInstance::worker_devtools_agent_route_id() const {
382 if (devtools_proxy_)
383 return devtools_proxy_->agent_route_id();
384 return MSG_ROUTING_NONE;
385 }
386
371 MessagePortMessageFilter* EmbeddedWorkerInstance::message_port_message_filter() 387 MessagePortMessageFilter* EmbeddedWorkerInstance::message_port_message_filter()
372 const { 388 const {
373 return registry_->MessagePortMessageFilterForProcess(process_id_); 389 return registry_->MessagePortMessageFilterForProcess(process_id_);
374 } 390 }
375 391
376 void EmbeddedWorkerInstance::AddListener(Listener* listener) { 392 void EmbeddedWorkerInstance::AddListener(Listener* listener) {
377 listener_list_.AddObserver(listener); 393 listener_list_.AddObserver(listener);
378 } 394 }
379 395
380 void EmbeddedWorkerInstance::RemoveListener(Listener* listener) { 396 void EmbeddedWorkerInstance::RemoveListener(Listener* listener) {
381 listener_list_.RemoveObserver(listener); 397 listener_list_.RemoveObserver(listener);
382 } 398 }
383 399
384 } // namespace content 400 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/embedded_worker_instance.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698