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 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(int64 registration_id
,
381 const GURL
& pattern
) override
{
382 web_ui_
->CallJavascriptFunction("serviceworker.onRegistrationDeleted",
383 StringValue(pattern
.spec()));
385 int partition_id() const { return partition_id_
; }
388 const int partition_id_
;
389 WebUI
* const web_ui_
;
392 ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI
* web_ui
)
393 : WebUIController(web_ui
), next_partition_id_(0) {
394 WebUIDataSource
* source
=
395 WebUIDataSource::Create(kChromeUIServiceWorkerInternalsHost
);
396 source
->SetJsonPath("strings.js");
397 source
->AddResourcePath("serviceworker_internals.js",
398 IDR_SERVICE_WORKER_INTERNALS_JS
);
399 source
->AddResourcePath("serviceworker_internals.css",
400 IDR_SERVICE_WORKER_INTERNALS_CSS
);
401 source
->SetDefaultResource(IDR_SERVICE_WORKER_INTERNALS_HTML
);
402 source
->DisableDenyXFrameOptions();
404 BrowserContext
* browser_context
=
405 web_ui
->GetWebContents()->GetBrowserContext();
406 WebUIDataSource::Add(browser_context
, source
);
408 web_ui
->RegisterMessageCallback(
410 base::Bind(&ServiceWorkerInternalsUI::GetOptions
,
411 base::Unretained(this)));
412 web_ui
->RegisterMessageCallback(
414 base::Bind(&ServiceWorkerInternalsUI::SetOption
, base::Unretained(this)));
415 web_ui
->RegisterMessageCallback(
416 "getAllRegistrations",
417 base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations
,
418 base::Unretained(this)));
419 web_ui
->RegisterMessageCallback(
421 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod
,
422 base::Unretained(this),
423 &ServiceWorkerVersion::StopWorker
));
424 web_ui
->RegisterMessageCallback(
426 base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod
,
427 base::Unretained(this),
428 &ServiceWorkerVersion::DispatchSyncEvent
));
429 web_ui
->RegisterMessageCallback(
431 base::Bind(&ServiceWorkerInternalsUI::DispatchPushEvent
,
432 base::Unretained(this)));
433 web_ui
->RegisterMessageCallback(
435 base::Bind(&ServiceWorkerInternalsUI::InspectWorker
,
436 base::Unretained(this)));
437 web_ui
->RegisterMessageCallback(
439 base::Bind(&ServiceWorkerInternalsUI::Unregister
,
440 base::Unretained(this)));
441 web_ui
->RegisterMessageCallback(
443 base::Bind(&ServiceWorkerInternalsUI::StartWorker
,
444 base::Unretained(this)));
447 ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() {
448 BrowserContext
* browser_context
=
449 web_ui()->GetWebContents()->GetBrowserContext();
450 // Safe to use base::Unretained(this) because
451 // ForEachStoragePartition is synchronous.
452 BrowserContext::StoragePartitionCallback remove_observer_cb
=
453 base::Bind(&ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition
,
454 base::Unretained(this));
455 BrowserContext::ForEachStoragePartition(browser_context
, remove_observer_cb
);
458 void ServiceWorkerInternalsUI::GetOptions(const ListValue
* args
) {
459 DictionaryValue options
;
460 options
.SetBoolean("debug_on_start",
461 ServiceWorkerDevToolsManager::GetInstance()
462 ->debug_service_worker_on_start());
463 web_ui()->CallJavascriptFunction("serviceworker.onOptions", options
);
466 void ServiceWorkerInternalsUI::SetOption(const ListValue
* args
) {
467 std::string option_name
;
469 if (!args
->GetString(0, &option_name
) || option_name
!= "debug_on_start" ||
470 !args
->GetBoolean(1, &option_boolean
)) {
473 ServiceWorkerDevToolsManager::GetInstance()
474 ->set_debug_service_worker_on_start(option_boolean
);
477 void ServiceWorkerInternalsUI::GetAllRegistrations(const ListValue
* args
) {
478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
479 BrowserContext
* browser_context
=
480 web_ui()->GetWebContents()->GetBrowserContext();
481 // Safe to use base::Unretained(this) because
482 // ForEachStoragePartition is synchronous.
483 BrowserContext::StoragePartitionCallback add_context_cb
=
484 base::Bind(&ServiceWorkerInternalsUI::AddContextFromStoragePartition
,
485 base::Unretained(this));
486 BrowserContext::ForEachStoragePartition(browser_context
, add_context_cb
);
489 void ServiceWorkerInternalsUI::AddContextFromStoragePartition(
490 StoragePartition
* partition
) {
491 int partition_id
= 0;
492 scoped_refptr
<ServiceWorkerContextWrapper
> context
=
493 static_cast<ServiceWorkerContextWrapper
*>(
494 partition
->GetServiceWorkerContext());
495 if (PartitionObserver
* observer
=
496 observers_
.get(reinterpret_cast<uintptr_t>(partition
))) {
497 partition_id
= observer
->partition_id();
499 partition_id
= next_partition_id_
++;
500 scoped_ptr
<PartitionObserver
> new_observer(
501 new PartitionObserver(partition_id
, web_ui()));
502 context
->AddObserver(new_observer
.get());
503 observers_
.set(reinterpret_cast<uintptr_t>(partition
), new_observer
.Pass());
506 BrowserThread::PostTask(
509 base::Bind(GetRegistrationsOnIOThread
,
511 base::Bind(OnStoredRegistrations
,
513 base::Bind(OnAllRegistrations
,
516 context
->is_incognito()
518 : partition
->GetPath()))));
521 void ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition(
522 StoragePartition
* partition
) {
523 scoped_ptr
<PartitionObserver
> observer(
524 observers_
.take_and_erase(reinterpret_cast<uintptr_t>(partition
)));
527 scoped_refptr
<ServiceWorkerContextWrapper
> context
=
528 static_cast<ServiceWorkerContextWrapper
*>(
529 partition
->GetServiceWorkerContext());
530 context
->RemoveObserver(observer
.get());
533 void ServiceWorkerInternalsUI::FindContext(
535 StoragePartition
** result_partition
,
536 StoragePartition
* storage_partition
) const {
537 PartitionObserver
* observer
=
538 observers_
.get(reinterpret_cast<uintptr_t>(storage_partition
));
539 if (observer
&& partition_id
== observer
->partition_id()) {
540 *result_partition
= storage_partition
;
544 bool ServiceWorkerInternalsUI::GetServiceWorkerContext(
546 scoped_refptr
<ServiceWorkerContextWrapper
>* context
) const {
547 BrowserContext
* browser_context
=
548 web_ui()->GetWebContents()->GetBrowserContext();
549 StoragePartition
* result_partition(NULL
);
550 BrowserContext::StoragePartitionCallback find_context_cb
=
551 base::Bind(&ServiceWorkerInternalsUI::FindContext
,
552 base::Unretained(this),
555 BrowserContext::ForEachStoragePartition(browser_context
, find_context_cb
);
556 if (!result_partition
)
558 *context
= static_cast<ServiceWorkerContextWrapper
*>(
559 result_partition
->GetServiceWorkerContext());
563 void ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod(
564 ServiceWorkerVersionMethod method
,
565 const ListValue
* args
) {
566 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
568 const DictionaryValue
* cmd_args
= NULL
;
570 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
571 std::string version_id_string
;
572 int64 version_id
= 0;
573 if (!args
->GetInteger(0, &callback_id
) ||
574 !args
->GetDictionary(1, &cmd_args
) ||
575 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
576 !GetServiceWorkerContext(partition_id
, &context
) ||
577 !cmd_args
->GetString("version_id", &version_id_string
) ||
578 !base::StringToInt64(version_id_string
, &version_id
)) {
582 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
583 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
584 CallServiceWorkerVersionMethodWithVersionID(
585 method
, context
, version_id
, callback
);
588 void ServiceWorkerInternalsUI::DispatchPushEvent(
589 const ListValue
* args
) {
590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
593 int64 version_id
= 0;
594 std::string version_id_string
;
595 const DictionaryValue
* cmd_args
= NULL
;
596 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
597 if (!args
->GetInteger(0, &callback_id
) ||
598 !args
->GetDictionary(1, &cmd_args
) ||
599 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
600 !GetServiceWorkerContext(partition_id
, &context
) ||
601 !cmd_args
->GetString("version_id", &version_id_string
) ||
602 !base::StringToInt64(version_id_string
, &version_id
)) {
606 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
607 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
608 DispatchPushEventWithVersionID(context
, version_id
, callback
);
611 void ServiceWorkerInternalsUI::InspectWorker(const ListValue
* args
) {
612 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
614 const DictionaryValue
* cmd_args
= NULL
;
616 int devtools_agent_route_id
= 0;
617 if (!args
->GetInteger(0, &callback_id
) ||
618 !args
->GetDictionary(1, &cmd_args
) ||
619 !cmd_args
->GetInteger("process_id", &process_id
) ||
620 !cmd_args
->GetInteger("devtools_agent_route_id",
621 &devtools_agent_route_id
)) {
624 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
625 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
626 scoped_refptr
<DevToolsAgentHostImpl
> agent_host(
627 ServiceWorkerDevToolsManager::GetInstance()
628 ->GetDevToolsAgentHostForWorker(process_id
, devtools_agent_route_id
));
629 if (!agent_host
.get()) {
630 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
633 agent_host
->Inspect(web_ui()->GetWebContents()->GetBrowserContext());
634 callback
.Run(SERVICE_WORKER_OK
);
637 void ServiceWorkerInternalsUI::Unregister(const ListValue
* args
) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
641 std::string scope_string
;
642 const DictionaryValue
* cmd_args
= NULL
;
643 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
644 if (!args
->GetInteger(0, &callback_id
) ||
645 !args
->GetDictionary(1, &cmd_args
) ||
646 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
647 !GetServiceWorkerContext(partition_id
, &context
) ||
648 !cmd_args
->GetString("scope", &scope_string
)) {
652 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
653 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
654 UnregisterWithScope(context
, GURL(scope_string
), callback
);
657 void ServiceWorkerInternalsUI::StartWorker(const ListValue
* args
) {
658 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
661 std::string scope_string
;
662 const DictionaryValue
* cmd_args
= NULL
;
663 scoped_refptr
<ServiceWorkerContextWrapper
> context
;
664 if (!args
->GetInteger(0, &callback_id
) ||
665 !args
->GetDictionary(1, &cmd_args
) ||
666 !cmd_args
->GetInteger("partition_id", &partition_id
) ||
667 !GetServiceWorkerContext(partition_id
, &context
) ||
668 !cmd_args
->GetString("scope", &scope_string
)) {
672 base::Callback
<void(ServiceWorkerStatusCode
)> callback
=
673 base::Bind(OperationCompleteCallback
, AsWeakPtr(), callback_id
);
674 FindRegistrationForPattern(
675 context
, GURL(scope_string
), base::Bind(StartActiveWorker
, callback
));
678 } // namespace content