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/devtools_manager_impl.h"
16 #include "content/browser/devtools/embedded_worker_devtools_manager.h"
17 #include "content/browser/service_worker/service_worker_context_observer.h"
18 #include "content/browser/service_worker/service_worker_context_wrapper.h"
19 #include "content/browser/service_worker/service_worker_registration.h"
20 #include "content/browser/service_worker/service_worker_version.h"
21 #include "content/grit/content_resources.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/storage_partition.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/browser/web_ui.h"
27 #include "content/public/browser/web_ui_data_source.h"
28 #include "content/public/common/url_constants.h"
30 using base::DictionaryValue
;
31 using base::FundamentalValue
;
32 using base::ListValue
;
33 using base::StringValue
;
41 void OperationCompleteCallback(WeakPtr
<ServiceWorkerInternalsUI
> internals
,
43 ServiceWorkerStatusCode status
) {
44 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
45 BrowserThread::PostTask(
48 base::Bind(OperationCompleteCallback
, internals
, callback_id
, status
));
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
53 internals
->web_ui()->CallJavascriptFunction(
54 "serviceworker.onOperationComplete",
55 FundamentalValue(static_cast<int>(status
)),
56 FundamentalValue(callback_id
));
60 void CallServiceWorkerVersionMethodWithVersionID(
61 ServiceWorkerInternalsUI::ServiceWorkerVersionMethod method
,
62 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
64 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
65 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
66 BrowserThread::PostTask(
69 base::Bind(CallServiceWorkerVersionMethodWithVersionID
,
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
77 scoped_refptr
<ServiceWorkerVersion
> version
=
78 context
->context()->GetLiveVersion(version_id
);
80 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
83 (*version
.get().*method
)(callback
);
86 void DispatchPushEventWithVersionID(
87 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
89 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
90 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
91 BrowserThread::PostTask(
94 base::Bind(DispatchPushEventWithVersionID
,
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
101 scoped_refptr
<ServiceWorkerVersion
> version
=
102 context
->context()->GetLiveVersion(version_id
);
103 if (!version
.get()) {
104 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
107 std::string data
= "Test push message from ServiceWorkerInternals.";
108 version
->DispatchPushEvent(callback
, data
);
111 void UnregisterWithScope(
112 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
114 const ServiceWorkerInternalsUI::StatusCallback
& callback
) {
115 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
116 BrowserThread::PostTask(
119 base::Bind(UnregisterWithScope
, context
, scope
, callback
));
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
123 context
->context()->UnregisterServiceWorker(scope
, callback
);
126 void WorkerStarted(const scoped_refptr
<ServiceWorkerRegistration
>& registration
,
127 const ServiceWorkerInternalsUI::StatusCallback
& callback
,
128 ServiceWorkerStatusCode status
) {
129 callback
.Run(status
);
132 void StartActiveWorker(
133 const ServiceWorkerInternalsUI::StatusCallback
& callback
,
134 ServiceWorkerStatusCode status
,
135 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
137 if (status
== SERVICE_WORKER_OK
) {
138 // Pass the reference of |registration| to WorkerStarted callback to prevent
139 // it from being deleted while starting the worker. If the refcount of
140 // |registration| is 1, it will be deleted after WorkerStarted is called.
141 registration
->active_version()->StartWorker(
142 base::Bind(WorkerStarted
, registration
, callback
));
145 callback
.Run(SERVICE_WORKER_ERROR_NOT_FOUND
);
148 void FindRegistrationForPattern(
149 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
151 const ServiceWorkerStorage::FindRegistrationCallback callback
) {
152 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
153 BrowserThread::PostTask(
156 base::Bind(FindRegistrationForPattern
, context
, scope
, callback
));
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
160 context
->context()->storage()->FindRegistrationForPattern(scope
, callback
);
163 void UpdateVersionInfo(const ServiceWorkerVersionInfo
& version
,
164 DictionaryValue
* info
) {
165 switch (version
.running_status
) {
166 case ServiceWorkerVersion::STOPPED
:
167 info
->SetString("running_status", "STOPPED");
169 case ServiceWorkerVersion::STARTING
:
170 info
->SetString("running_status", "STARTING");
172 case ServiceWorkerVersion::RUNNING
:
173 info
->SetString("running_status", "RUNNING");
175 case ServiceWorkerVersion::STOPPING
:
176 info
->SetString("running_status", "STOPPING");
180 switch (version
.status
) {
181 case ServiceWorkerVersion::NEW
:
182 info
->SetString("status", "NEW");
184 case ServiceWorkerVersion::INSTALLING
:
185 info
->SetString("status", "INSTALLING");
187 case ServiceWorkerVersion::INSTALLED
:
188 info
->SetString("status", "INSTALLED");
190 case ServiceWorkerVersion::ACTIVATING
:
191 info
->SetString("status", "ACTIVATING");
193 case ServiceWorkerVersion::ACTIVATED
:
194 info
->SetString("status", "ACTIVATED");
196 case ServiceWorkerVersion::REDUNDANT
:
197 info
->SetString("status", "REDUNDANT");
200 info
->SetString("script_url", version
.script_url
.spec());
201 info
->SetString("version_id", base::Int64ToString(version
.version_id
));
202 info
->SetInteger("process_id", version
.process_id
);
203 info
->SetInteger("thread_id", version
.thread_id
);
204 info
->SetInteger("devtools_agent_route_id", version
.devtools_agent_route_id
);
207 ListValue
* GetRegistrationListValue(
208 const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
) {
209 ListValue
* result
= new ListValue();
210 for (std::vector
<ServiceWorkerRegistrationInfo
>::const_iterator it
=
211 registrations
.begin();
212 it
!= registrations
.end();
214 const ServiceWorkerRegistrationInfo
& registration
= *it
;
215 DictionaryValue
* registration_info
= new DictionaryValue();
216 registration_info
->SetString("scope", registration
.pattern
.spec());
217 registration_info
->SetString(
218 "registration_id", base::Int64ToString(registration
.registration_id
));
220 if (!registration
.active_version
.is_null
) {
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
.is_null
) {
227 DictionaryValue
* waiting_info
= new DictionaryValue();
228 UpdateVersionInfo(registration
.waiting_version
, waiting_info
);
229 registration_info
->Set("waiting", waiting_info
);
232 result
->Append(registration_info
);
237 ListValue
* GetVersionListValue(
238 const std::vector
<ServiceWorkerVersionInfo
>& versions
) {
239 ListValue
* result
= new ListValue();
240 for (std::vector
<ServiceWorkerVersionInfo
>::const_iterator it
=
242 it
!= versions
.end();
244 DictionaryValue
* info
= new DictionaryValue();
245 UpdateVersionInfo(*it
, info
);
246 result
->Append(info
);
251 void GetRegistrationsOnIOThread(
252 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
253 base::Callback
<void(const std::vector
<ServiceWorkerRegistrationInfo
>&)>
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
256 context
->context()->storage()->GetAllRegistrations(callback
);
259 void OnStoredRegistrations(
260 scoped_refptr
<ServiceWorkerContextWrapper
> context
,
261 base::Callback
<void(const std::vector
<ServiceWorkerRegistrationInfo
>&,
262 const std::vector
<ServiceWorkerVersionInfo
>&,
263 const std::vector
<ServiceWorkerRegistrationInfo
>&)>
265 const std::vector
<ServiceWorkerRegistrationInfo
>& stored_registrations
) {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
267 BrowserThread::PostTask(
271 context
->context()->GetAllLiveRegistrationInfo(),
272 context
->context()->GetAllLiveVersionInfo(),
273 stored_registrations
));
276 void OnAllRegistrations(
277 WeakPtr
<ServiceWorkerInternalsUI
> internals
,
279 const base::FilePath
& context_path
,
280 const std::vector
<ServiceWorkerRegistrationInfo
>& live_registrations
,
281 const std::vector
<ServiceWorkerVersionInfo
>& live_versions
,
282 const std::vector
<ServiceWorkerRegistrationInfo
>& stored_registrations
) {
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
287 ScopedVector
<const Value
> args
;
288 args
.push_back(GetRegistrationListValue(live_registrations
));
289 args
.push_back(GetVersionListValue(live_versions
));
290 args
.push_back(GetRegistrationListValue(stored_registrations
));
291 args
.push_back(new FundamentalValue(partition_id
));
292 args
.push_back(new StringValue(context_path
.value()));
293 internals
->web_ui()->CallJavascriptFunction("serviceworker.onPartitionData",
299 class ServiceWorkerInternalsUI::PartitionObserver
300 : public ServiceWorkerContextObserver
{
302 PartitionObserver(int partition_id
, WebUI
* web_ui
)
303 : partition_id_(partition_id
), web_ui_(web_ui
) {}
304 virtual ~PartitionObserver() {}
305 // ServiceWorkerContextObserver overrides:
306 virtual void OnWorkerStarted(int64 version_id
,
308 int thread_id
) OVERRIDE
{
309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
310 web_ui_
->CallJavascriptFunction(
311 "serviceworker.onWorkerStarted",
312 FundamentalValue(partition_id_
),
313 StringValue(base::Int64ToString(version_id
)),
314 FundamentalValue(process_id
),
315 FundamentalValue(thread_id
));
317 virtual void OnWorkerStopped(int64 version_id
,
319 int thread_id
) OVERRIDE
{
320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
321 web_ui_
->CallJavascriptFunction(
322 "serviceworker.onWorkerStopped",
323 FundamentalValue(partition_id_
),
324 StringValue(base::Int64ToString(version_id
)),
325 FundamentalValue(process_id
),
326 FundamentalValue(thread_id
));
328 virtual void OnVersionStateChanged(int64 version_id
) OVERRIDE
{
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
330 web_ui_
->CallJavascriptFunction(
331 "serviceworker.onVersionStateChanged",
332 FundamentalValue(partition_id_
),
333 StringValue(base::Int64ToString(version_id
)));
335 virtual void OnErrorReported(int64 version_id
,
338 const ErrorInfo
& info
) OVERRIDE
{
339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
340 ScopedVector
<const Value
> args
;
341 args
.push_back(new FundamentalValue(partition_id_
));
342 args
.push_back(new StringValue(base::Int64ToString(version_id
)));
343 args
.push_back(new FundamentalValue(process_id
));
344 args
.push_back(new FundamentalValue(thread_id
));
345 scoped_ptr
<DictionaryValue
> value(new DictionaryValue());
346 value
->SetString("message", info
.error_message
);
347 value
->SetInteger("lineNumber", info
.line_number
);
348 value
->SetInteger("columnNumber", info
.column_number
);
349 value
->SetString("sourceURL", info
.source_url
.spec());
350 args
.push_back(value
.release());
351 web_ui_
->CallJavascriptFunction("serviceworker.onErrorReported",
354 virtual void OnReportConsoleMessage(int64 version_id
,
357 const ConsoleMessage
& message
) OVERRIDE
{
358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
359 ScopedVector
<const Value
> args
;
360 args
.push_back(new FundamentalValue(partition_id_
));
361 args
.push_back(new StringValue(base::Int64ToString(version_id
)));
362 args
.push_back(new FundamentalValue(process_id
));
363 args
.push_back(new FundamentalValue(thread_id
));
364 scoped_ptr
<DictionaryValue
> value(new DictionaryValue());
365 value
->SetInteger("sourceIdentifier", message
.source_identifier
);
366 value
->SetInteger("message_level", message
.message_level
);
367 value
->SetString("message", message
.message
);
368 value
->SetInteger("lineNumber", message
.line_number
);
369 value
->SetString("sourceURL", message
.source_url
.spec());
370 args
.push_back(value
.release());
371 web_ui_
->CallJavascriptFunction("serviceworker.onConsoleMessageReported",
374 virtual void OnRegistrationStored(const GURL
& pattern
) OVERRIDE
{
375 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
376 web_ui_
->CallJavascriptFunction("serviceworker.onRegistrationStored",
377 StringValue(pattern
.spec()));
379 virtual void OnRegistrationDeleted(const GURL
& pattern
) OVERRIDE
{
380 web_ui_
->CallJavascriptFunction("serviceworker.onRegistrationDeleted",
381 StringValue(pattern
.spec()));
383 int partition_id() const { return partition_id_
; }
386 const int partition_id_
;
387 WebUI
* const web_ui_
;
390 ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI
* web_ui
)
391 : WebUIController(web_ui
), next_partition_id_(0) {
392 WebUIDataSource
* source
=
393 WebUIDataSource::Create(kChromeUIServiceWorkerInternalsHost
);
394 source
->SetUseJsonJSFormatV2();
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