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/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
;
40 void OperationCompleteCallback(WeakPtr
<ServiceWorkerInternalsUI
> internals
,
42 ServiceWorkerStatusCode status
) {
43 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
44 BrowserThread::PostTask(
47 base::Bind(OperationCompleteCallback
, internals
, callback_id
, status
));
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
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
,
63 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
64 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
65 BrowserThread::PostTask(
68 base::Bind(CallServiceWorkerVersionMethodWithVersionID
,
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
76 scoped_refptr
<ServiceWorkerVersion
> version
=
77 context
->context()->GetLiveVersion(version_id
);
79 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
82 (*version
.get().*method
)(callback
);
85 void DispatchPushEventWithVersionID(
86 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
88 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
89 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
90 BrowserThread::PostTask(
93 base::Bind(DispatchPushEventWithVersionID
,
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
);
106 std::string data
= "Test push message from ServiceWorkerInternals.";
107 version
->DispatchPushEvent(callback
, data
);
110 void UnregisterWithScope(
111 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
113 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
114 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
115 BrowserThread::PostTask(
118 base::Bind(UnregisterWithScope
, context
, scope
, callback
));
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
));
144 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
147 void FindRegistrationForPattern(
148 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
150 const ServiceWorkerStorage::FindRegistrationCallback callback
) {
151 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
152 BrowserThread::PostTask(
155 base::Bind(FindRegistrationForPattern
, context
, scope
, callback
));
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");
168 case ServiceWorkerVersion::STARTING
:
169 info
->SetString("running_status", "STARTING");
171 case ServiceWorkerVersion::RUNNING
:
172 info
->SetString("running_status", "RUNNING");
174 case ServiceWorkerVersion::STOPPING
:
175 info
->SetString("running_status", "STOPPING");
179 switch (version
.status
) {
180 case ServiceWorkerVersion::NEW
:
181 info
->SetString("status", "NEW");
183 case ServiceWorkerVersion::INSTALLING
:
184 info
->SetString("status", "INSTALLING");
186 case ServiceWorkerVersion::INSTALLED
:
187 info
->SetString("status", "INSTALLED");
189 case ServiceWorkerVersion::ACTIVATING
:
190 info
->SetString("status", "ACTIVATING");
192 case ServiceWorkerVersion::ACTIVATED
:
193 info
->SetString("status", "ACTIVATED");
195 case ServiceWorkerVersion::REDUNDANT
:
196 info
->SetString("status", "REDUNDANT");
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();
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
);
238 ListValue
* GetVersionListValue(
239 const std::vector
<ServiceWorkerVersionInfo
>& versions
) {
240 ListValue
* result
= new ListValue();
241 for (std::vector
<ServiceWorkerVersionInfo
>::const_iterator it
=
243 it
!= versions
.end();
245 DictionaryValue
* info
= new DictionaryValue();
246 UpdateVersionInfo(*it
, info
);
247 result
->Append(info
);
252 void GetRegistrationsOnIOThread(
253 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
254 base::Callback
<void(const std::vector
<ServiceWorkerRegistrationInfo
>&)>
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
>&)>
266 const std::vector
<ServiceWorkerRegistrationInfo
>& stored_registrations
) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
268 BrowserThread::PostTask(
272 context
->context()->GetAllLiveRegistrationInfo(),
273 context
->context()->GetAllLiveVersionInfo(),
274 stored_registrations
));
277 void OnAllRegistrations(
278 WeakPtr
<ServiceWorkerInternalsUI
> internals
,
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
));
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",
300 class ServiceWorkerInternalsUI::PartitionObserver
301 : public ServiceWorkerContextObserver
{
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
,
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
,
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
,
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",
355 void OnReportConsoleMessage(int64 version_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",
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_
; }
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(
409 base::Bind(&ServiceWorkerInternalsUI::GetOptions
,
410 base::Unretained(this)));
411 web_ui
->RegisterMessageCallback(
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(
420 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod
,
421 base::Unretained(this),
422 &ServiceWorkerVersion::StopWorker
));
423 web_ui
->RegisterMessageCallback(
425 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod
,
426 base::Unretained(this),
427 &ServiceWorkerVersion::DispatchSyncEvent
));
428 web_ui
->RegisterMessageCallback(
430 base::Bind(&ServiceWorkerInternalsUI::DispatchPushEvent
,
431 base::Unretained(this)));
432 web_ui
->RegisterMessageCallback(
434 base::Bind(&ServiceWorkerInternalsUI::InspectWorker
,
435 base::Unretained(this)));
436 web_ui
->RegisterMessageCallback(
438 base::Bind(&ServiceWorkerInternalsUI::Unregister
,
439 base::Unretained(this)));
440 web_ui
->RegisterMessageCallback(
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
;
468 if (!args
->GetString(0, &option_name
) || option_name
!= "debug_on_start" ||
469 !args
->GetBoolean(1, &option_boolean
)) {
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();
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(
508 base::Bind(GetRegistrationsOnIOThread
,
510 base::Bind(OnStoredRegistrations
,
512 base::Bind(OnAllRegistrations
,
515 context
->is_incognito()
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
)));
526 scoped_refptr
<ServiceWorkerContextWrapper
> context
=
527 static_cast<ServiceWorkerContextWrapper
*>(
528 partition
->GetServiceWorkerContext());
529 context
->RemoveObserver(observer
.get());
532 void ServiceWorkerInternalsUI::FindContext(
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(
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),
554 BrowserContext::ForEachStoragePartition(browser_context
, find_context_cb
);
555 if (!result_partition
)
557 *context
= static_cast<ServiceWorkerContextWrapper
*>(
558 result_partition
->GetServiceWorkerContext());
562 void ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod(
563 ServiceWorkerVersionMethod method
,
564 const ListValue
* args
) {
565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
567 const DictionaryValue
* cmd_args
= NULL
;
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
)) {
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
));
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
)) {
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
));
613 const DictionaryValue
* cmd_args
= NULL
;
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
)) {
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
);
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
));
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
)) {
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
));
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
)) {
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