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"
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/service_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
;
40 using GetRegistrationsCallback
=
41 base::Callback
<void(const std::vector
<ServiceWorkerRegistrationInfo
>&,
42 const std::vector
<ServiceWorkerVersionInfo
>&,
43 const std::vector
<ServiceWorkerRegistrationInfo
>&)>;
45 void OperationCompleteCallback(WeakPtr
<ServiceWorkerInternalsUI
> internals
,
47 ServiceWorkerStatusCode status
) {
48 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
49 BrowserThread::PostTask(
52 base::Bind(OperationCompleteCallback
, internals
, callback_id
, status
));
55 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
57 internals
->web_ui()->CallJavascriptFunction(
58 "serviceworker.onOperationComplete",
59 FundamentalValue(static_cast<int>(status
)),
60 FundamentalValue(callback_id
));
64 void CallServiceWorkerVersionMethodWithVersionID(
65 ServiceWorkerInternalsUI::ServiceWorkerVersionMethod method
,
66 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
68 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
69 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
70 BrowserThread::PostTask(
73 base::Bind(CallServiceWorkerVersionMethodWithVersionID
,
81 if (!context
->context()) {
82 callback
.Run(SERVICE_WORKER_ERROR_ABORT
);
86 scoped_refptr
<ServiceWorkerVersion
> version
=
87 context
->context()->GetLiveVersion(version_id
);
89 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
92 (*version
.get().*method
)(callback
);
95 void DispatchPushEventWithVersionID(
96 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
98 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
99 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
100 BrowserThread::PostTask(
103 base::Bind(DispatchPushEventWithVersionID
,
110 if (!context
->context()) {
111 callback
.Run(SERVICE_WORKER_ERROR_ABORT
);
115 scoped_refptr
<ServiceWorkerVersion
> version
=
116 context
->context()->GetLiveVersion(version_id
);
117 if (!version
.get()) {
118 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
121 std::string data
= "Test push message from ServiceWorkerInternals.";
122 version
->DispatchPushEvent(callback
, data
);
125 void UnregisterWithScope(
126 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
128 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
129 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
130 BrowserThread::PostTask(
133 base::Bind(UnregisterWithScope
, context
, scope
, callback
));
137 if (!context
->context()) {
138 callback
.Run(SERVICE_WORKER_ERROR_ABORT
);
141 context
->context()->UnregisterServiceWorker(scope
, callback
);
144 void FindRegistrationForPattern(
145 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
147 const ServiceWorkerStorage::FindRegistrationCallback callback
) {
148 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
149 BrowserThread::PostTask(
152 base::Bind(FindRegistrationForPattern
, context
, scope
, callback
));
156 if (!context
->context()) {
157 callback
.Run(SERVICE_WORKER_ERROR_ABORT
,
158 scoped_refptr
<ServiceWorkerRegistration
>());
161 context
->context()->storage()->FindRegistrationForPattern(scope
, callback
);
164 void UpdateVersionInfo(const ServiceWorkerVersionInfo
& version
,
165 DictionaryValue
* info
) {
166 switch (version
.running_status
) {
167 case ServiceWorkerVersion::STOPPED
:
168 info
->SetString("running_status", "STOPPED");
170 case ServiceWorkerVersion::STARTING
:
171 info
->SetString("running_status", "STARTING");
173 case ServiceWorkerVersion::RUNNING
:
174 info
->SetString("running_status", "RUNNING");
176 case ServiceWorkerVersion::STOPPING
:
177 info
->SetString("running_status", "STOPPING");
181 switch (version
.status
) {
182 case ServiceWorkerVersion::NEW
:
183 info
->SetString("status", "NEW");
185 case ServiceWorkerVersion::INSTALLING
:
186 info
->SetString("status", "INSTALLING");
188 case ServiceWorkerVersion::INSTALLED
:
189 info
->SetString("status", "INSTALLED");
191 case ServiceWorkerVersion::ACTIVATING
:
192 info
->SetString("status", "ACTIVATING");
194 case ServiceWorkerVersion::ACTIVATED
:
195 info
->SetString("status", "ACTIVATED");
197 case ServiceWorkerVersion::REDUNDANT
:
198 info
->SetString("status", "REDUNDANT");
201 info
->SetString("script_url", version
.script_url
.spec());
202 info
->SetString("version_id", base::Int64ToString(version
.version_id
));
203 info
->SetInteger("process_id", version
.process_id
);
204 info
->SetInteger("thread_id", version
.thread_id
);
205 info
->SetInteger("devtools_agent_route_id", version
.devtools_agent_route_id
);
208 ListValue
* GetRegistrationListValue(
209 const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
) {
210 ListValue
* result
= new ListValue();
211 for (std::vector
<ServiceWorkerRegistrationInfo
>::const_iterator it
=
212 registrations
.begin();
213 it
!= registrations
.end();
215 const ServiceWorkerRegistrationInfo
& registration
= *it
;
216 DictionaryValue
* registration_info
= new DictionaryValue();
217 registration_info
->SetString("scope", registration
.pattern
.spec());
218 registration_info
->SetString(
219 "registration_id", base::Int64ToString(registration
.registration_id
));
221 if (registration
.active_version
.version_id
!=
222 kInvalidServiceWorkerVersionId
) {
223 DictionaryValue
* active_info
= new DictionaryValue();
224 UpdateVersionInfo(registration
.active_version
, active_info
);
225 registration_info
->Set("active", active_info
);
228 if (registration
.waiting_version
.version_id
!=
229 kInvalidServiceWorkerVersionId
) {
230 DictionaryValue
* waiting_info
= new DictionaryValue();
231 UpdateVersionInfo(registration
.waiting_version
, waiting_info
);
232 registration_info
->Set("waiting", waiting_info
);
235 result
->Append(registration_info
);
240 ListValue
* GetVersionListValue(
241 const std::vector
<ServiceWorkerVersionInfo
>& versions
) {
242 ListValue
* result
= new ListValue();
243 for (std::vector
<ServiceWorkerVersionInfo
>::const_iterator it
=
245 it
!= versions
.end();
247 DictionaryValue
* info
= new DictionaryValue();
248 UpdateVersionInfo(*it
, info
);
249 result
->Append(info
);
254 void DidGetStoredRegistrationsOnIOThread(
255 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
256 const GetRegistrationsCallback
& callback
,
257 const std::vector
<ServiceWorkerRegistrationInfo
>& stored_registrations
) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
259 if (!context
->context()) {
260 BrowserThread::PostTask(
261 BrowserThread::UI
, FROM_HERE
,
262 base::Bind(callback
, std::vector
<ServiceWorkerRegistrationInfo
>(),
263 std::vector
<ServiceWorkerVersionInfo
>(),
264 std::vector
<ServiceWorkerRegistrationInfo
>()));
268 BrowserThread::PostTask(
272 context
->context()->GetAllLiveRegistrationInfo(),
273 context
->context()->GetAllLiveVersionInfo(),
274 stored_registrations
));
277 void GetRegistrationsOnIOThread(
278 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
279 const GetRegistrationsCallback
& callback
) {
280 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
281 if (!context
->context()) {
282 BrowserThread::PostTask(
283 BrowserThread::UI
, FROM_HERE
,
284 base::Bind(callback
, std::vector
<ServiceWorkerRegistrationInfo
>(),
285 std::vector
<ServiceWorkerVersionInfo
>(),
286 std::vector
<ServiceWorkerRegistrationInfo
>()));
289 context
->context()->storage()->GetAllRegistrations(
290 base::Bind(DidGetStoredRegistrationsOnIOThread
, context
, callback
));
293 void DidGetRegistrations(
294 WeakPtr
<ServiceWorkerInternalsUI
> internals
,
296 const base::FilePath
& context_path
,
297 const std::vector
<ServiceWorkerRegistrationInfo
>& live_registrations
,
298 const std::vector
<ServiceWorkerVersionInfo
>& live_versions
,
299 const std::vector
<ServiceWorkerRegistrationInfo
>& stored_registrations
) {
300 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
304 ScopedVector
<const Value
> args
;
305 args
.push_back(GetRegistrationListValue(live_registrations
));
306 args
.push_back(GetVersionListValue(live_versions
));
307 args
.push_back(GetRegistrationListValue(stored_registrations
));
308 args
.push_back(new FundamentalValue(partition_id
));
309 args
.push_back(new StringValue(context_path
.value()));
310 internals
->web_ui()->CallJavascriptFunction("serviceworker.onPartitionData",
316 class ServiceWorkerInternalsUI::PartitionObserver
317 : public ServiceWorkerContextObserver
{
319 PartitionObserver(int partition_id
, WebUI
* web_ui
)
320 : partition_id_(partition_id
), web_ui_(web_ui
) {}
321 ~PartitionObserver() override
{}
322 // ServiceWorkerContextObserver overrides:
323 void OnRunningStateChanged(int64 version_id
,
324 ServiceWorkerVersion::RunningStatus
) override
{
325 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
326 web_ui_
->CallJavascriptFunction(
327 "serviceworker.onRunningStateChanged", FundamentalValue(partition_id_
),
328 StringValue(base::Int64ToString(version_id
)));
330 void OnVersionStateChanged(int64 version_id
,
331 ServiceWorkerVersion::Status
) override
{
332 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
333 web_ui_
->CallJavascriptFunction(
334 "serviceworker.onVersionStateChanged",
335 FundamentalValue(partition_id_
),
336 StringValue(base::Int64ToString(version_id
)));
338 void OnErrorReported(int64 version_id
,
341 const ErrorInfo
& info
) override
{
342 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
343 ScopedVector
<const Value
> args
;
344 args
.push_back(new FundamentalValue(partition_id_
));
345 args
.push_back(new StringValue(base::Int64ToString(version_id
)));
346 args
.push_back(new FundamentalValue(process_id
));
347 args
.push_back(new FundamentalValue(thread_id
));
348 scoped_ptr
<DictionaryValue
> value(new DictionaryValue());
349 value
->SetString("message", info
.error_message
);
350 value
->SetInteger("lineNumber", info
.line_number
);
351 value
->SetInteger("columnNumber", info
.column_number
);
352 value
->SetString("sourceURL", info
.source_url
.spec());
353 args
.push_back(value
.release());
354 web_ui_
->CallJavascriptFunction("serviceworker.onErrorReported",
357 void OnReportConsoleMessage(int64 version_id
,
360 const ConsoleMessage
& message
) override
{
361 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
362 ScopedVector
<const Value
> args
;
363 args
.push_back(new FundamentalValue(partition_id_
));
364 args
.push_back(new StringValue(base::Int64ToString(version_id
)));
365 args
.push_back(new FundamentalValue(process_id
));
366 args
.push_back(new FundamentalValue(thread_id
));
367 scoped_ptr
<DictionaryValue
> value(new DictionaryValue());
368 value
->SetInteger("sourceIdentifier", message
.source_identifier
);
369 value
->SetInteger("message_level", message
.message_level
);
370 value
->SetString("message", message
.message
);
371 value
->SetInteger("lineNumber", message
.line_number
);
372 value
->SetString("sourceURL", message
.source_url
.spec());
373 args
.push_back(value
.release());
374 web_ui_
->CallJavascriptFunction("serviceworker.onConsoleMessageReported",
377 void OnRegistrationStored(int64 registration_id
,
378 const GURL
& pattern
) override
{
379 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
380 web_ui_
->CallJavascriptFunction("serviceworker.onRegistrationStored",
381 StringValue(pattern
.spec()));
383 void OnRegistrationDeleted(int64 registration_id
,
384 const GURL
& pattern
) override
{
385 web_ui_
->CallJavascriptFunction("serviceworker.onRegistrationDeleted",
386 StringValue(pattern
.spec()));
388 int partition_id() const { return partition_id_
; }
391 const int partition_id_
;
392 WebUI
* const web_ui_
;
395 ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI
* web_ui
)
396 : WebUIController(web_ui
), next_partition_id_(0) {
397 WebUIDataSource
* source
=
398 WebUIDataSource::Create(kChromeUIServiceWorkerInternalsHost
);
399 source
->SetJsonPath("strings.js");
400 source
->AddResourcePath("serviceworker_internals.js",
401 IDR_SERVICE_WORKER_INTERNALS_JS
);
402 source
->AddResourcePath("serviceworker_internals.css",
403 IDR_SERVICE_WORKER_INTERNALS_CSS
);
404 source
->SetDefaultResource(IDR_SERVICE_WORKER_INTERNALS_HTML
);
405 source
->DisableDenyXFrameOptions();
407 BrowserContext
* browser_context
=
408 web_ui
->GetWebContents()->GetBrowserContext();
409 WebUIDataSource::Add(browser_context
, source
);
411 web_ui
->RegisterMessageCallback(
413 base::Bind(&ServiceWorkerInternalsUI::GetOptions
,
414 base::Unretained(this)));
415 web_ui
->RegisterMessageCallback(
417 base::Bind(&ServiceWorkerInternalsUI::SetOption
, base::Unretained(this)));
418 web_ui
->RegisterMessageCallback(
419 "getAllRegistrations",
420 base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations
,
421 base::Unretained(this)));
422 web_ui
->RegisterMessageCallback(
424 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod
,
425 base::Unretained(this),
426 &ServiceWorkerVersion::StopWorker
));
427 web_ui
->RegisterMessageCallback(
429 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod
,
430 base::Unretained(this),
431 &ServiceWorkerVersion::DispatchSyncEvent
));
432 web_ui
->RegisterMessageCallback(
434 base::Bind(&ServiceWorkerInternalsUI::DispatchPushEvent
,
435 base::Unretained(this)));
436 web_ui
->RegisterMessageCallback(
438 base::Bind(&ServiceWorkerInternalsUI::InspectWorker
,
439 base::Unretained(this)));
440 web_ui
->RegisterMessageCallback(
442 base::Bind(&ServiceWorkerInternalsUI::Unregister
,
443 base::Unretained(this)));
444 web_ui
->RegisterMessageCallback(
446 base::Bind(&ServiceWorkerInternalsUI::StartWorker
,
447 base::Unretained(this)));
450 ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() {
451 BrowserContext
* browser_context
=
452 web_ui()->GetWebContents()->GetBrowserContext();
453 // Safe to use base::Unretained(this) because
454 // ForEachStoragePartition is synchronous.
455 BrowserContext::StoragePartitionCallback remove_observer_cb
=
456 base::Bind(&ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition
,
457 base::Unretained(this));
458 BrowserContext::ForEachStoragePartition(browser_context
, remove_observer_cb
);
461 void ServiceWorkerInternalsUI::GetOptions(const ListValue
* args
) {
462 DictionaryValue options
;
463 options
.SetBoolean("debug_on_start",
464 ServiceWorkerDevToolsManager::GetInstance()
465 ->debug_service_worker_on_start());
466 web_ui()->CallJavascriptFunction("serviceworker.onOptions", options
);
469 void ServiceWorkerInternalsUI::SetOption(const ListValue
* args
) {
470 std::string option_name
;
472 if (!args
->GetString(0, &option_name
) || option_name
!= "debug_on_start" ||
473 !args
->GetBoolean(1, &option_boolean
)) {
476 ServiceWorkerDevToolsManager::GetInstance()
477 ->set_debug_service_worker_on_start(option_boolean
);
480 void ServiceWorkerInternalsUI::GetAllRegistrations(const ListValue
* args
) {
481 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
482 BrowserContext
* browser_context
=
483 web_ui()->GetWebContents()->GetBrowserContext();
484 // Safe to use base::Unretained(this) because
485 // ForEachStoragePartition is synchronous.
486 BrowserContext::StoragePartitionCallback add_context_cb
=
487 base::Bind(&ServiceWorkerInternalsUI::AddContextFromStoragePartition
,
488 base::Unretained(this));
489 BrowserContext::ForEachStoragePartition(browser_context
, add_context_cb
);
492 void ServiceWorkerInternalsUI::AddContextFromStoragePartition(
493 StoragePartition
* partition
) {
494 int partition_id
= 0;
495 scoped_refptr
<ServiceWorkerContextWrapper
> context
=
496 static_cast<ServiceWorkerContextWrapper
*>(
497 partition
->GetServiceWorkerContext());
498 if (PartitionObserver
* observer
=
499 observers_
.get(reinterpret_cast<uintptr_t>(partition
))) {
500 partition_id
= observer
->partition_id();
502 partition_id
= next_partition_id_
++;
503 scoped_ptr
<PartitionObserver
> new_observer(
504 new PartitionObserver(partition_id
, web_ui()));
505 context
->AddObserver(new_observer
.get());
506 observers_
.set(reinterpret_cast<uintptr_t>(partition
), new_observer
.Pass());
509 BrowserThread::PostTask(
510 BrowserThread::IO
, FROM_HERE
,
511 base::Bind(GetRegistrationsOnIOThread
, context
,
512 base::Bind(DidGetRegistrations
, AsWeakPtr(), partition_id
,
513 context
->is_incognito() ? base::FilePath()
514 : partition
->GetPath())));
517 void ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition(
518 StoragePartition
* partition
) {
519 scoped_ptr
<PartitionObserver
> observer(
520 observers_
.take_and_erase(reinterpret_cast<uintptr_t>(partition
)));
523 scoped_refptr
<ServiceWorkerContextWrapper
> context
=
524 static_cast<ServiceWorkerContextWrapper
*>(
525 partition
->GetServiceWorkerContext());
526 context
->RemoveObserver(observer
.get());
529 void ServiceWorkerInternalsUI::FindContext(
531 StoragePartition
** result_partition
,
532 StoragePartition
* storage_partition
) const {
533 PartitionObserver
* observer
=
534 observers_
.get(reinterpret_cast<uintptr_t>(storage_partition
));
535 if (observer
&& partition_id
== observer
->partition_id()) {
536 *result_partition
= storage_partition
;
540 bool ServiceWorkerInternalsUI::GetServiceWorkerContext(
542 scoped_refptr
<ServiceWorkerContextWrapper
>* context
) const {
543 BrowserContext
* browser_context
=
544 web_ui()->GetWebContents()->GetBrowserContext();
545 StoragePartition
* result_partition(NULL
);
546 BrowserContext::StoragePartitionCallback find_context_cb
=
547 base::Bind(&ServiceWorkerInternalsUI::FindContext
,
548 base::Unretained(this),
551 BrowserContext::ForEachStoragePartition(browser_context
, find_context_cb
);
552 if (!result_partition
)
554 *context
= static_cast<ServiceWorkerContextWrapper
*>(
555 result_partition
->GetServiceWorkerContext());
559 void ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod(
560 ServiceWorkerVersionMethod method
,
561 const ListValue
* args
) {
562 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
564 const DictionaryValue
* cmd_args
= NULL
;
566 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
567 std::string version_id_string
;
568 int64 version_id
= 0;
569 if (!args
->GetInteger(0, &callback_id
) ||
570 !args
->GetDictionary(1, &cmd_args
) ||
571 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
572 !GetServiceWorkerContext(partition_id
, &context
) ||
573 !cmd_args
->GetString("version_id", &version_id_string
) ||
574 !base::StringToInt64(version_id_string
, &version_id
)) {
578 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
579 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
580 CallServiceWorkerVersionMethodWithVersionID(
581 method
, context
, version_id
, callback
);
584 void ServiceWorkerInternalsUI::DispatchPushEvent(
585 const ListValue
* args
) {
586 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
589 int64 version_id
= 0;
590 std::string version_id_string
;
591 const DictionaryValue
* cmd_args
= NULL
;
592 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
593 if (!args
->GetInteger(0, &callback_id
) ||
594 !args
->GetDictionary(1, &cmd_args
) ||
595 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
596 !GetServiceWorkerContext(partition_id
, &context
) ||
597 !cmd_args
->GetString("version_id", &version_id_string
) ||
598 !base::StringToInt64(version_id_string
, &version_id
)) {
602 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
603 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
604 DispatchPushEventWithVersionID(context
, version_id
, callback
);
607 void ServiceWorkerInternalsUI::InspectWorker(const ListValue
* args
) {
608 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
610 const DictionaryValue
* cmd_args
= NULL
;
612 int devtools_agent_route_id
= 0;
613 if (!args
->GetInteger(0, &callback_id
) ||
614 !args
->GetDictionary(1, &cmd_args
) ||
615 !cmd_args
->GetInteger("process_id", &process_id
) ||
616 !cmd_args
->GetInteger("devtools_agent_route_id",
617 &devtools_agent_route_id
)) {
620 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
621 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
622 scoped_refptr
<DevToolsAgentHostImpl
> agent_host(
623 ServiceWorkerDevToolsManager::GetInstance()
624 ->GetDevToolsAgentHostForWorker(process_id
, devtools_agent_route_id
));
625 if (!agent_host
.get()) {
626 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
629 agent_host
->Inspect(web_ui()->GetWebContents()->GetBrowserContext());
630 callback
.Run(SERVICE_WORKER_OK
);
633 void ServiceWorkerInternalsUI::Unregister(const ListValue
* args
) {
634 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
637 std::string scope_string
;
638 const DictionaryValue
* cmd_args
= NULL
;
639 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
640 if (!args
->GetInteger(0, &callback_id
) ||
641 !args
->GetDictionary(1, &cmd_args
) ||
642 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
643 !GetServiceWorkerContext(partition_id
, &context
) ||
644 !cmd_args
->GetString("scope", &scope_string
)) {
648 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
649 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
650 UnregisterWithScope(context
, GURL(scope_string
), callback
);
653 void ServiceWorkerInternalsUI::StartWorker(const ListValue
* args
) {
654 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
657 std::string scope_string
;
658 const DictionaryValue
* cmd_args
= NULL
;
659 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
660 if (!args
->GetInteger(0, &callback_id
) ||
661 !args
->GetDictionary(1, &cmd_args
) ||
662 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
663 !GetServiceWorkerContext(partition_id
, &context
) ||
664 !cmd_args
->GetString("scope", &scope_string
)) {
667 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
668 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
669 context
->StartServiceWorker(GURL(scope_string
), callback
);
672 } // namespace content