Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_internals_ui.cc
bloba7c8d71681356b90951808a176feef67971efce7
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 "content/browser/service_worker/service_worker_internals_ui.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/values.h"
14 #include "content/browser/devtools/devtools_agent_host_impl.h"
15 #include "content/browser/devtools/embedded_worker_devtools_manager.h"
16 #include "content/browser/service_worker/service_worker_context_observer.h"
17 #include "content/browser/service_worker/service_worker_context_wrapper.h"
18 #include "content/browser/service_worker/service_worker_registration.h"
19 #include "content/browser/service_worker/service_worker_version.h"
20 #include "content/grit/content_resources.h"
21 #include "content/public/browser/browser_context.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/storage_partition.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/browser/web_ui.h"
26 #include "content/public/browser/web_ui_data_source.h"
27 #include "content/public/common/url_constants.h"
29 using base::DictionaryValue;
30 using base::FundamentalValue;
31 using base::ListValue;
32 using base::StringValue;
33 using base::Value;
34 using base::WeakPtr;
36 namespace content {
38 namespace {
40 void OperationCompleteCallback(WeakPtr<ServiceWorkerInternalsUI> internals,
41 int callback_id,
42 ServiceWorkerStatusCode status) {
43 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
44 BrowserThread::PostTask(
45 BrowserThread::UI,
46 FROM_HERE,
47 base::Bind(OperationCompleteCallback, internals, callback_id, status));
48 return;
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 if (internals) {
52 internals->web_ui()->CallJavascriptFunction(
53 "serviceworker.onOperationComplete",
54 FundamentalValue(static_cast<int>(status)),
55 FundamentalValue(callback_id));
59 void CallServiceWorkerVersionMethodWithVersionID(
60 ServiceWorkerInternalsUI::ServiceWorkerVersionMethod method,
61 scoped_refptr<ServiceWorkerContextWrapper> context,
62 int64 version_id,
63 const ServiceWorkerInternalsUI::StatusCallback& callback) {
64 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
65 BrowserThread::PostTask(
66 BrowserThread::IO,
67 FROM_HERE,
68 base::Bind(CallServiceWorkerVersionMethodWithVersionID,
69 method,
70 context,
71 version_id,
72 callback));
73 return;
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
76 scoped_refptr<ServiceWorkerVersion> version =
77 context->context()->GetLiveVersion(version_id);
78 if (!version.get()) {
79 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
80 return;
82 (*version.get().*method)(callback);
85 void DispatchPushEventWithVersionID(
86 scoped_refptr<ServiceWorkerContextWrapper> context,
87 int64 version_id,
88 const ServiceWorkerInternalsUI::StatusCallback& callback) {
89 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
90 BrowserThread::PostTask(
91 BrowserThread::IO,
92 FROM_HERE,
93 base::Bind(DispatchPushEventWithVersionID,
94 context,
95 version_id,
96 callback));
97 return;
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
100 scoped_refptr<ServiceWorkerVersion> version =
101 context->context()->GetLiveVersion(version_id);
102 if (!version.get()) {
103 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
104 return;
106 std::string data = "Test push message from ServiceWorkerInternals.";
107 version->DispatchPushEvent(callback, data);
110 void UnregisterWithScope(
111 scoped_refptr<ServiceWorkerContextWrapper> context,
112 const GURL& scope,
113 const ServiceWorkerInternalsUI::StatusCallback& callback) {
114 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
115 BrowserThread::PostTask(
116 BrowserThread::IO,
117 FROM_HERE,
118 base::Bind(UnregisterWithScope, context, scope, callback));
119 return;
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
122 context->context()->UnregisterServiceWorker(scope, callback);
125 void WorkerStarted(const scoped_refptr<ServiceWorkerRegistration>& registration,
126 const ServiceWorkerInternalsUI::StatusCallback& callback,
127 ServiceWorkerStatusCode status) {
128 callback.Run(status);
131 void StartActiveWorker(
132 const ServiceWorkerInternalsUI::StatusCallback& callback,
133 ServiceWorkerStatusCode status,
134 const scoped_refptr<ServiceWorkerRegistration>& registration) {
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
136 if (status == SERVICE_WORKER_OK) {
137 // Pass the reference of |registration| to WorkerStarted callback to prevent
138 // it from being deleted while starting the worker. If the refcount of
139 // |registration| is 1, it will be deleted after WorkerStarted is called.
140 registration->active_version()->StartWorker(
141 base::Bind(WorkerStarted, registration, callback));
142 return;
144 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
147 void FindRegistrationForPattern(
148 scoped_refptr<ServiceWorkerContextWrapper> context,
149 const GURL& scope,
150 const ServiceWorkerStorage::FindRegistrationCallback callback) {
151 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
152 BrowserThread::PostTask(
153 BrowserThread::IO,
154 FROM_HERE,
155 base::Bind(FindRegistrationForPattern, context, scope, callback));
156 return;
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
159 context->context()->storage()->FindRegistrationForPattern(scope, callback);
162 void UpdateVersionInfo(const ServiceWorkerVersionInfo& version,
163 DictionaryValue* info) {
164 switch (version.running_status) {
165 case ServiceWorkerVersion::STOPPED:
166 info->SetString("running_status", "STOPPED");
167 break;
168 case ServiceWorkerVersion::STARTING:
169 info->SetString("running_status", "STARTING");
170 break;
171 case ServiceWorkerVersion::RUNNING:
172 info->SetString("running_status", "RUNNING");
173 break;
174 case ServiceWorkerVersion::STOPPING:
175 info->SetString("running_status", "STOPPING");
176 break;
179 switch (version.status) {
180 case ServiceWorkerVersion::NEW:
181 info->SetString("status", "NEW");
182 break;
183 case ServiceWorkerVersion::INSTALLING:
184 info->SetString("status", "INSTALLING");
185 break;
186 case ServiceWorkerVersion::INSTALLED:
187 info->SetString("status", "INSTALLED");
188 break;
189 case ServiceWorkerVersion::ACTIVATING:
190 info->SetString("status", "ACTIVATING");
191 break;
192 case ServiceWorkerVersion::ACTIVATED:
193 info->SetString("status", "ACTIVATED");
194 break;
195 case ServiceWorkerVersion::REDUNDANT:
196 info->SetString("status", "REDUNDANT");
197 break;
199 info->SetString("script_url", version.script_url.spec());
200 info->SetString("version_id", base::Int64ToString(version.version_id));
201 info->SetInteger("process_id", version.process_id);
202 info->SetInteger("thread_id", version.thread_id);
203 info->SetInteger("devtools_agent_route_id", version.devtools_agent_route_id);
206 ListValue* GetRegistrationListValue(
207 const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
208 ListValue* result = new ListValue();
209 for (std::vector<ServiceWorkerRegistrationInfo>::const_iterator it =
210 registrations.begin();
211 it != registrations.end();
212 ++it) {
213 const ServiceWorkerRegistrationInfo& registration = *it;
214 DictionaryValue* registration_info = new DictionaryValue();
215 registration_info->SetString("scope", registration.pattern.spec());
216 registration_info->SetString(
217 "registration_id", base::Int64ToString(registration.registration_id));
219 if (registration.active_version.version_id !=
220 kInvalidServiceWorkerVersionId) {
221 DictionaryValue* active_info = new DictionaryValue();
222 UpdateVersionInfo(registration.active_version, active_info);
223 registration_info->Set("active", active_info);
226 if (registration.waiting_version.version_id !=
227 kInvalidServiceWorkerVersionId) {
228 DictionaryValue* waiting_info = new DictionaryValue();
229 UpdateVersionInfo(registration.waiting_version, waiting_info);
230 registration_info->Set("waiting", waiting_info);
233 result->Append(registration_info);
235 return result;
238 ListValue* GetVersionListValue(
239 const std::vector<ServiceWorkerVersionInfo>& versions) {
240 ListValue* result = new ListValue();
241 for (std::vector<ServiceWorkerVersionInfo>::const_iterator it =
242 versions.begin();
243 it != versions.end();
244 ++it) {
245 DictionaryValue* info = new DictionaryValue();
246 UpdateVersionInfo(*it, info);
247 result->Append(info);
249 return result;
252 void GetRegistrationsOnIOThread(
253 scoped_refptr<ServiceWorkerContextWrapper> context,
254 base::Callback<void(const std::vector<ServiceWorkerRegistrationInfo>&)>
255 callback) {
256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
257 context->context()->storage()->GetAllRegistrations(callback);
260 void OnStoredRegistrations(
261 scoped_refptr<ServiceWorkerContextWrapper> context,
262 base::Callback<void(const std::vector<ServiceWorkerRegistrationInfo>&,
263 const std::vector<ServiceWorkerVersionInfo>&,
264 const std::vector<ServiceWorkerRegistrationInfo>&)>
265 callback,
266 const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
268 BrowserThread::PostTask(
269 BrowserThread::UI,
270 FROM_HERE,
271 base::Bind(callback,
272 context->context()->GetAllLiveRegistrationInfo(),
273 context->context()->GetAllLiveVersionInfo(),
274 stored_registrations));
277 void OnAllRegistrations(
278 WeakPtr<ServiceWorkerInternalsUI> internals,
279 int partition_id,
280 const base::FilePath& context_path,
281 const std::vector<ServiceWorkerRegistrationInfo>& live_registrations,
282 const std::vector<ServiceWorkerVersionInfo>& live_versions,
283 const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285 if (!internals)
286 return;
288 ScopedVector<const Value> args;
289 args.push_back(GetRegistrationListValue(live_registrations));
290 args.push_back(GetVersionListValue(live_versions));
291 args.push_back(GetRegistrationListValue(stored_registrations));
292 args.push_back(new FundamentalValue(partition_id));
293 args.push_back(new StringValue(context_path.value()));
294 internals->web_ui()->CallJavascriptFunction("serviceworker.onPartitionData",
295 args.get());
298 } // namespace
300 class ServiceWorkerInternalsUI::PartitionObserver
301 : public ServiceWorkerContextObserver {
302 public:
303 PartitionObserver(int partition_id, WebUI* web_ui)
304 : partition_id_(partition_id), web_ui_(web_ui) {}
305 ~PartitionObserver() override {}
306 // ServiceWorkerContextObserver overrides:
307 void OnWorkerStarted(int64 version_id,
308 int process_id,
309 int thread_id) override {
310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
311 web_ui_->CallJavascriptFunction(
312 "serviceworker.onWorkerStarted",
313 FundamentalValue(partition_id_),
314 StringValue(base::Int64ToString(version_id)),
315 FundamentalValue(process_id),
316 FundamentalValue(thread_id));
318 void OnWorkerStopped(int64 version_id,
319 int process_id,
320 int thread_id) override {
321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
322 web_ui_->CallJavascriptFunction(
323 "serviceworker.onWorkerStopped",
324 FundamentalValue(partition_id_),
325 StringValue(base::Int64ToString(version_id)),
326 FundamentalValue(process_id),
327 FundamentalValue(thread_id));
329 void OnVersionStateChanged(int64 version_id) override {
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
331 web_ui_->CallJavascriptFunction(
332 "serviceworker.onVersionStateChanged",
333 FundamentalValue(partition_id_),
334 StringValue(base::Int64ToString(version_id)));
336 void OnErrorReported(int64 version_id,
337 int process_id,
338 int thread_id,
339 const ErrorInfo& info) override {
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
341 ScopedVector<const Value> args;
342 args.push_back(new FundamentalValue(partition_id_));
343 args.push_back(new StringValue(base::Int64ToString(version_id)));
344 args.push_back(new FundamentalValue(process_id));
345 args.push_back(new FundamentalValue(thread_id));
346 scoped_ptr<DictionaryValue> value(new DictionaryValue());
347 value->SetString("message", info.error_message);
348 value->SetInteger("lineNumber", info.line_number);
349 value->SetInteger("columnNumber", info.column_number);
350 value->SetString("sourceURL", info.source_url.spec());
351 args.push_back(value.release());
352 web_ui_->CallJavascriptFunction("serviceworker.onErrorReported",
353 args.get());
355 void OnReportConsoleMessage(int64 version_id,
356 int process_id,
357 int thread_id,
358 const ConsoleMessage& message) override {
359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
360 ScopedVector<const Value> args;
361 args.push_back(new FundamentalValue(partition_id_));
362 args.push_back(new StringValue(base::Int64ToString(version_id)));
363 args.push_back(new FundamentalValue(process_id));
364 args.push_back(new FundamentalValue(thread_id));
365 scoped_ptr<DictionaryValue> value(new DictionaryValue());
366 value->SetInteger("sourceIdentifier", message.source_identifier);
367 value->SetInteger("message_level", message.message_level);
368 value->SetString("message", message.message);
369 value->SetInteger("lineNumber", message.line_number);
370 value->SetString("sourceURL", message.source_url.spec());
371 args.push_back(value.release());
372 web_ui_->CallJavascriptFunction("serviceworker.onConsoleMessageReported",
373 args.get());
375 void OnRegistrationStored(const GURL& pattern) override {
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
377 web_ui_->CallJavascriptFunction("serviceworker.onRegistrationStored",
378 StringValue(pattern.spec()));
380 void OnRegistrationDeleted(const GURL& pattern) override {
381 web_ui_->CallJavascriptFunction("serviceworker.onRegistrationDeleted",
382 StringValue(pattern.spec()));
384 int partition_id() const { return partition_id_; }
386 private:
387 const int partition_id_;
388 WebUI* const web_ui_;
391 ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui)
392 : WebUIController(web_ui), next_partition_id_(0) {
393 WebUIDataSource* source =
394 WebUIDataSource::Create(kChromeUIServiceWorkerInternalsHost);
395 source->SetJsonPath("strings.js");
396 source->AddResourcePath("serviceworker_internals.js",
397 IDR_SERVICE_WORKER_INTERNALS_JS);
398 source->AddResourcePath("serviceworker_internals.css",
399 IDR_SERVICE_WORKER_INTERNALS_CSS);
400 source->SetDefaultResource(IDR_SERVICE_WORKER_INTERNALS_HTML);
401 source->DisableDenyXFrameOptions();
403 BrowserContext* browser_context =
404 web_ui->GetWebContents()->GetBrowserContext();
405 WebUIDataSource::Add(browser_context, source);
407 web_ui->RegisterMessageCallback(
408 "GetOptions",
409 base::Bind(&ServiceWorkerInternalsUI::GetOptions,
410 base::Unretained(this)));
411 web_ui->RegisterMessageCallback(
412 "SetOption",
413 base::Bind(&ServiceWorkerInternalsUI::SetOption, base::Unretained(this)));
414 web_ui->RegisterMessageCallback(
415 "getAllRegistrations",
416 base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations,
417 base::Unretained(this)));
418 web_ui->RegisterMessageCallback(
419 "stop",
420 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod,
421 base::Unretained(this),
422 &ServiceWorkerVersion::StopWorker));
423 web_ui->RegisterMessageCallback(
424 "sync",
425 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod,
426 base::Unretained(this),
427 &ServiceWorkerVersion::DispatchSyncEvent));
428 web_ui->RegisterMessageCallback(
429 "push",
430 base::Bind(&ServiceWorkerInternalsUI::DispatchPushEvent,
431 base::Unretained(this)));
432 web_ui->RegisterMessageCallback(
433 "inspect",
434 base::Bind(&ServiceWorkerInternalsUI::InspectWorker,
435 base::Unretained(this)));
436 web_ui->RegisterMessageCallback(
437 "unregister",
438 base::Bind(&ServiceWorkerInternalsUI::Unregister,
439 base::Unretained(this)));
440 web_ui->RegisterMessageCallback(
441 "start",
442 base::Bind(&ServiceWorkerInternalsUI::StartWorker,
443 base::Unretained(this)));
446 ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() {
447 BrowserContext* browser_context =
448 web_ui()->GetWebContents()->GetBrowserContext();
449 // Safe to use base::Unretained(this) because
450 // ForEachStoragePartition is synchronous.
451 BrowserContext::StoragePartitionCallback remove_observer_cb =
452 base::Bind(&ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition,
453 base::Unretained(this));
454 BrowserContext::ForEachStoragePartition(browser_context, remove_observer_cb);
457 void ServiceWorkerInternalsUI::GetOptions(const ListValue* args) {
458 DictionaryValue options;
459 options.SetBoolean("debug_on_start",
460 EmbeddedWorkerDevToolsManager::GetInstance()
461 ->debug_service_worker_on_start());
462 web_ui()->CallJavascriptFunction("serviceworker.onOptions", options);
465 void ServiceWorkerInternalsUI::SetOption(const ListValue* args) {
466 std::string option_name;
467 bool option_boolean;
468 if (!args->GetString(0, &option_name) || option_name != "debug_on_start" ||
469 !args->GetBoolean(1, &option_boolean)) {
470 return;
472 EmbeddedWorkerDevToolsManager::GetInstance()
473 ->set_debug_service_worker_on_start(option_boolean);
476 void ServiceWorkerInternalsUI::GetAllRegistrations(const ListValue* args) {
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
478 BrowserContext* browser_context =
479 web_ui()->GetWebContents()->GetBrowserContext();
480 // Safe to use base::Unretained(this) because
481 // ForEachStoragePartition is synchronous.
482 BrowserContext::StoragePartitionCallback add_context_cb =
483 base::Bind(&ServiceWorkerInternalsUI::AddContextFromStoragePartition,
484 base::Unretained(this));
485 BrowserContext::ForEachStoragePartition(browser_context, add_context_cb);
488 void ServiceWorkerInternalsUI::AddContextFromStoragePartition(
489 StoragePartition* partition) {
490 int partition_id = 0;
491 scoped_refptr<ServiceWorkerContextWrapper> context =
492 static_cast<ServiceWorkerContextWrapper*>(
493 partition->GetServiceWorkerContext());
494 if (PartitionObserver* observer =
495 observers_.get(reinterpret_cast<uintptr_t>(partition))) {
496 partition_id = observer->partition_id();
497 } else {
498 partition_id = next_partition_id_++;
499 scoped_ptr<PartitionObserver> new_observer(
500 new PartitionObserver(partition_id, web_ui()));
501 context->AddObserver(new_observer.get());
502 observers_.set(reinterpret_cast<uintptr_t>(partition), new_observer.Pass());
505 BrowserThread::PostTask(
506 BrowserThread::IO,
507 FROM_HERE,
508 base::Bind(GetRegistrationsOnIOThread,
509 context,
510 base::Bind(OnStoredRegistrations,
511 context,
512 base::Bind(OnAllRegistrations,
513 AsWeakPtr(),
514 partition_id,
515 context->is_incognito()
516 ? base::FilePath()
517 : partition->GetPath()))));
520 void ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition(
521 StoragePartition* partition) {
522 scoped_ptr<PartitionObserver> observer(
523 observers_.take_and_erase(reinterpret_cast<uintptr_t>(partition)));
524 if (!observer.get())
525 return;
526 scoped_refptr<ServiceWorkerContextWrapper> context =
527 static_cast<ServiceWorkerContextWrapper*>(
528 partition->GetServiceWorkerContext());
529 context->RemoveObserver(observer.get());
532 void ServiceWorkerInternalsUI::FindContext(
533 int partition_id,
534 StoragePartition** result_partition,
535 StoragePartition* storage_partition) const {
536 PartitionObserver* observer =
537 observers_.get(reinterpret_cast<uintptr_t>(storage_partition));
538 if (observer && partition_id == observer->partition_id()) {
539 *result_partition = storage_partition;
543 bool ServiceWorkerInternalsUI::GetServiceWorkerContext(
544 int partition_id,
545 scoped_refptr<ServiceWorkerContextWrapper>* context) const {
546 BrowserContext* browser_context =
547 web_ui()->GetWebContents()->GetBrowserContext();
548 StoragePartition* result_partition(NULL);
549 BrowserContext::StoragePartitionCallback find_context_cb =
550 base::Bind(&ServiceWorkerInternalsUI::FindContext,
551 base::Unretained(this),
552 partition_id,
553 &result_partition);
554 BrowserContext::ForEachStoragePartition(browser_context, find_context_cb);
555 if (!result_partition)
556 return false;
557 *context = static_cast<ServiceWorkerContextWrapper*>(
558 result_partition->GetServiceWorkerContext());
559 return true;
562 void ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod(
563 ServiceWorkerVersionMethod method,
564 const ListValue* args) {
565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
566 int callback_id;
567 const DictionaryValue* cmd_args = NULL;
568 int partition_id;
569 scoped_refptr<ServiceWorkerContextWrapper> context;
570 std::string version_id_string;
571 int64 version_id = 0;
572 if (!args->GetInteger(0, &callback_id) ||
573 !args->GetDictionary(1, &cmd_args) ||
574 !cmd_args->GetInteger("partition_id", &partition_id) ||
575 !GetServiceWorkerContext(partition_id, &context) ||
576 !cmd_args->GetString("version_id", &version_id_string) ||
577 !base::StringToInt64(version_id_string, &version_id)) {
578 return;
581 base::Callback<void(ServiceWorkerStatusCode)> callback =
582 base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
583 CallServiceWorkerVersionMethodWithVersionID(
584 method, context, version_id, callback);
587 void ServiceWorkerInternalsUI::DispatchPushEvent(
588 const ListValue* args) {
589 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
590 int callback_id;
591 int partition_id;
592 int64 version_id = 0;
593 std::string version_id_string;
594 const DictionaryValue* cmd_args = NULL;
595 scoped_refptr<ServiceWorkerContextWrapper> context;
596 if (!args->GetInteger(0, &callback_id) ||
597 !args->GetDictionary(1, &cmd_args) ||
598 !cmd_args->GetInteger("partition_id", &partition_id) ||
599 !GetServiceWorkerContext(partition_id, &context) ||
600 !cmd_args->GetString("version_id", &version_id_string) ||
601 !base::StringToInt64(version_id_string, &version_id)) {
602 return;
605 base::Callback<void(ServiceWorkerStatusCode)> callback =
606 base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
607 DispatchPushEventWithVersionID(context, version_id, callback);
610 void ServiceWorkerInternalsUI::InspectWorker(const ListValue* args) {
611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
612 int callback_id;
613 const DictionaryValue* cmd_args = NULL;
614 int process_id = 0;
615 int devtools_agent_route_id = 0;
616 if (!args->GetInteger(0, &callback_id) ||
617 !args->GetDictionary(1, &cmd_args) ||
618 !cmd_args->GetInteger("process_id", &process_id) ||
619 !cmd_args->GetInteger("devtools_agent_route_id",
620 &devtools_agent_route_id)) {
621 return;
623 base::Callback<void(ServiceWorkerStatusCode)> callback =
624 base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
625 scoped_refptr<DevToolsAgentHostImpl> agent_host(
626 EmbeddedWorkerDevToolsManager::GetInstance()
627 ->GetDevToolsAgentHostForWorker(process_id, devtools_agent_route_id));
628 if (!agent_host.get()) {
629 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND);
630 return;
632 agent_host->Inspect(web_ui()->GetWebContents()->GetBrowserContext());
633 callback.Run(SERVICE_WORKER_OK);
636 void ServiceWorkerInternalsUI::Unregister(const ListValue* args) {
637 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
638 int callback_id;
639 int partition_id;
640 std::string scope_string;
641 const DictionaryValue* cmd_args = NULL;
642 scoped_refptr<ServiceWorkerContextWrapper> context;
643 if (!args->GetInteger(0, &callback_id) ||
644 !args->GetDictionary(1, &cmd_args) ||
645 !cmd_args->GetInteger("partition_id", &partition_id) ||
646 !GetServiceWorkerContext(partition_id, &context) ||
647 !cmd_args->GetString("scope", &scope_string)) {
648 return;
651 base::Callback<void(ServiceWorkerStatusCode)> callback =
652 base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
653 UnregisterWithScope(context, GURL(scope_string), callback);
656 void ServiceWorkerInternalsUI::StartWorker(const ListValue* args) {
657 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
658 int callback_id;
659 int partition_id;
660 std::string scope_string;
661 const DictionaryValue* cmd_args = NULL;
662 scoped_refptr<ServiceWorkerContextWrapper> context;
663 if (!args->GetInteger(0, &callback_id) ||
664 !args->GetDictionary(1, &cmd_args) ||
665 !cmd_args->GetInteger("partition_id", &partition_id) ||
666 !GetServiceWorkerContext(partition_id, &context) ||
667 !cmd_args->GetString("scope", &scope_string)) {
668 return;
671 base::Callback<void(ServiceWorkerStatusCode)> callback =
672 base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
673 FindRegistrationForPattern(
674 context, GURL(scope_string), base::Bind(StartActiveWorker, callback));
677 } // namespace content