Index: content/browser/service_worker/service_worker_internals_ui.cc |
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc |
index 082229adf26d28146d738af658fed925655fc0e3..3ecda8fced160e3fe84302046300b57377263f73 100644 |
--- a/content/browser/service_worker/service_worker_internals_ui.cc |
+++ b/content/browser/service_worker/service_worker_internals_ui.cc |
@@ -35,66 +35,243 @@ using base::WeakPtr; |
namespace content { |
-// This class proxies calls to the ServiceWorker APIs on the IO |
-// thread, and then calls back JavaScript on the UI thread. |
-class ServiceWorkerInternalsUI::OperationProxy |
- : public base::RefCountedThreadSafe< |
- ServiceWorkerInternalsUI::OperationProxy> { |
- public: |
- OperationProxy(const WeakPtr<ServiceWorkerInternalsUI> internals, |
- scoped_ptr<ListValue> original_args) |
- : internals_(internals), original_args_(original_args.Pass()) {} |
- |
- void GetRegistrationsOnIOThread(int partition_id, |
- ServiceWorkerContextWrapper* context, |
- const base::FilePath& context_path); |
- void UnregisterOnIOThread(scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope); |
- void StartWorkerOnIOThread(scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope); |
- void StopWorkerOnIOThread(scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope); |
- void DispatchSyncEventToWorkerOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope); |
- void InspectWorkerOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope); |
+namespace { |
- private: |
- friend class base::RefCountedThreadSafe<OperationProxy>; |
- ~OperationProxy() {} |
- void OnHaveRegistrations( |
- int partition_id, |
- const base::FilePath& context_path, |
- const std::vector<ServiceWorkerRegistrationInfo>& registrations); |
- |
- void OperationComplete(ServiceWorkerStatusCode status); |
- |
- void StartActiveWorker( |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration); |
- |
- void StopActiveWorker( |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration); |
- |
- void DispatchSyncEventToActiveWorker( |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration); |
- |
- void InspectActiveWorker( |
- const ServiceWorkerContextCore* const service_worker_context, |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration); |
- |
- void InspectWorkerOnUIThread( |
- const ServiceWorkerContextCore* const service_worker_context, |
- int64 version_id); |
- |
- WeakPtr<ServiceWorkerInternalsUI> internals_; |
- scoped_ptr<ListValue> original_args_; |
-}; |
+typedef base::Callback<void(ServiceWorkerStatusCode)> StatusCallback; |
+typedef void (ServiceWorkerVersion::*ServiceWorkerVersionMethod)( |
+ const StatusCallback& callback); |
falken
2014/05/28 08:21:40
These typedefs are duplicated in the .h file.
horo
2014/05/28 09:06:39
Done.
|
+ |
+void OperationCompleteCallback( |
+ const WeakPtr<ServiceWorkerInternalsUI> internals, |
falken
2014/05/28 08:21:40
Chrome code doesn't seem to use const WeakPtr... I
horo
2014/05/28 09:06:39
Done.
|
+ int callback_id, |
+ ServiceWorkerStatusCode status) { |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(OperationCompleteCallback, internals, callback_id, status)); |
+ return; |
+ } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (internals) |
falken
2014/05/28 08:21:40
this if should probably have braces as the body ha
horo
2014/05/28 09:06:39
Done.
|
+ internals->web_ui()->CallJavascriptFunction( |
+ "serviceworker.onOperationComplete", |
+ FundamentalValue(static_cast<int>(status)), |
+ FundamentalValue(callback_id)); |
+} |
+ |
+void CallServiceWorkerVersionMethodWithVersionID( |
+ ServiceWorkerVersionMethod method, |
+ scoped_refptr<ServiceWorkerContextWrapper> context, |
+ int64 version_id, |
+ const StatusCallback& callback) { |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(CallServiceWorkerVersionMethodWithVersionID, |
+ method, |
+ context, |
+ version_id, |
+ callback)); |
+ return; |
+ } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ scoped_refptr<ServiceWorkerVersion> version = |
+ context->context()->GetLiveVersion(version_id); |
+ if (!version) { |
+ callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND); |
+ return; |
+ } |
+ (*version.*method)(callback); |
+} |
+ |
+void UnregisterWithScope(scoped_refptr<ServiceWorkerContextWrapper> context, |
+ const GURL& scope, |
+ const StatusCallback& callback) { |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(UnregisterWithScope, context, scope, callback)); |
+ return; |
+ } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ context->context()->UnregisterServiceWorker(scope, callback); |
+} |
+ |
+void WorkerStarted(const scoped_refptr<ServiceWorkerRegistration>& registration, |
+ const StatusCallback& callback, |
+ ServiceWorkerStatusCode status) { |
+ callback.Run(status); |
+} |
+ |
+void StartActiveWorker( |
+ const StatusCallback& callback, |
+ ServiceWorkerStatusCode status, |
+ const scoped_refptr<ServiceWorkerRegistration>& registration) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (status == SERVICE_WORKER_OK) { |
+ // Pass the reference of |registration| to WorkerStarted callback to prevent |
+ // it from being deleted while starting the worker. It the refcount of |
falken
2014/05/28 08:21:40
s/It/If/.... but why does StartWorker destroy the
horo
2014/05/28 09:06:39
Done.
If there is no ServiceWorkerHandle which has
|
+ // |registration| is 1, it will be deleted after WorkerStarted is called. |
+ registration->active_version()->StartWorker( |
+ base::Bind(WorkerStarted, registration, callback)); |
+ return; |
+ } |
+ callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND); |
+} |
+ |
+void FindRegistrationForPattern( |
+ scoped_refptr<ServiceWorkerContextWrapper> context, |
+ const GURL& scope, |
+ const ServiceWorkerStorage::FindRegistrationCallback callback) { |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(FindRegistrationForPattern, context, scope, callback)); |
+ return; |
+ } |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ context->context()->storage()->FindRegistrationForPattern(scope, callback); |
+} |
+ |
+void UpdateVersionInfo(const ServiceWorkerVersionInfo& version, |
+ DictionaryValue* info) { |
+ switch (version.running_status) { |
+ case ServiceWorkerVersion::STOPPED: |
+ info->SetString("running_status", "STOPPED"); |
+ break; |
+ case ServiceWorkerVersion::STARTING: |
+ info->SetString("running_status", "STARTING"); |
+ break; |
+ case ServiceWorkerVersion::RUNNING: |
+ info->SetString("running_status", "RUNNING"); |
+ break; |
+ case ServiceWorkerVersion::STOPPING: |
+ info->SetString("running_status", "STOPPING"); |
+ break; |
+ } |
+ |
+ switch (version.status) { |
+ case ServiceWorkerVersion::NEW: |
+ info->SetString("status", "NEW"); |
+ break; |
+ case ServiceWorkerVersion::INSTALLING: |
+ info->SetString("status", "INSTALLING"); |
+ break; |
+ case ServiceWorkerVersion::INSTALLED: |
+ info->SetString("status", "INSTALLED"); |
+ break; |
+ case ServiceWorkerVersion::ACTIVATING: |
+ info->SetString("status", "ACTIVATING"); |
+ break; |
+ case ServiceWorkerVersion::ACTIVE: |
+ info->SetString("status", "ACTIVE"); |
+ break; |
+ case ServiceWorkerVersion::DEACTIVATED: |
+ info->SetString("status", "DEACTIVATED"); |
+ break; |
+ } |
+ info->SetString("version_id", base::Int64ToString(version.version_id)); |
+ info->SetInteger("process_id", version.process_id); |
+ info->SetInteger("thread_id", version.thread_id); |
+ info->SetInteger("devtools_agent_route_id", version.devtools_agent_route_id); |
+} |
+ |
+ListValue* GetRegistrationListValue( |
+ const std::vector<ServiceWorkerRegistrationInfo>& registrations) { |
+ ListValue* result = new ListValue(); |
+ for (std::vector<ServiceWorkerRegistrationInfo>::const_iterator it = |
+ registrations.begin(); |
+ it != registrations.end(); |
+ ++it) { |
+ const ServiceWorkerRegistrationInfo& registration = *it; |
+ DictionaryValue* registration_info = new DictionaryValue(); |
+ registration_info->SetString("scope", registration.pattern.spec()); |
+ registration_info->SetString("script_url", registration.script_url.spec()); |
+ registration_info->SetString( |
+ "registration_id", base::Int64ToString(registration.registration_id)); |
+ |
+ if (!registration.active_version.is_null) { |
+ DictionaryValue* active_info = new DictionaryValue(); |
+ UpdateVersionInfo(registration.active_version, active_info); |
+ registration_info->Set("active", active_info); |
+ } |
+ |
+ if (!registration.pending_version.is_null) { |
+ DictionaryValue* pending_info = new DictionaryValue(); |
+ UpdateVersionInfo(registration.pending_version, pending_info); |
+ registration_info->Set("pending", pending_info); |
+ } |
+ |
+ result->Append(registration_info); |
+ } |
+ return result; |
+} |
+ |
+ListValue* GetVersionListValue( |
+ const std::vector<ServiceWorkerVersionInfo>& versions) { |
+ ListValue* result = new ListValue(); |
+ for (std::vector<ServiceWorkerVersionInfo>::const_iterator it = |
+ versions.begin(); |
+ it != versions.end(); |
+ ++it) { |
+ DictionaryValue* info = new DictionaryValue(); |
+ UpdateVersionInfo(*it, info); |
+ result->Append(info); |
+ } |
+ return result; |
+} |
+ |
+void GetRegistrationsOnIOThread( |
+ scoped_refptr<ServiceWorkerContextWrapper> context, |
+ base::Callback<void(const std::vector<ServiceWorkerRegistrationInfo>&)> |
+ callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ context->context()->storage()->GetAllRegistrations(callback); |
+} |
+ |
+void OnStoredRegistrations( |
+ scoped_refptr<ServiceWorkerContextWrapper> context, |
+ base::Callback<void(const std::vector<ServiceWorkerRegistrationInfo>&, |
+ const std::vector<ServiceWorkerVersionInfo>&, |
+ const std::vector<ServiceWorkerRegistrationInfo>&)> |
+ callback, |
+ const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(callback, |
+ context->context()->GetAllLiveRegistrationInfo(), |
+ context->context()->GetAllLiveVersionInfo(), |
+ stored_registrations)); |
+} |
+ |
+void OnAllRegistrations( |
+ const WeakPtr<ServiceWorkerInternalsUI> internals, |
falken
2014/05/28 08:21:40
const WeakPtr again
horo
2014/05/28 09:06:39
Done.
|
+ int partition_id, |
+ const base::FilePath& context_path, |
+ const std::vector<ServiceWorkerRegistrationInfo>& live_registrations, |
+ const std::vector<ServiceWorkerVersionInfo>& live_versions, |
+ const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!internals) |
+ return; |
+ |
+ ScopedVector<const Value> args; |
+ args.push_back(GetRegistrationListValue(live_registrations)); |
+ args.push_back(GetVersionListValue(live_versions)); |
+ args.push_back(GetRegistrationListValue(stored_registrations)); |
+ args.push_back(new FundamentalValue(partition_id)); |
+ args.push_back(new StringValue(context_path.value())); |
+ internals->web_ui()->CallJavascriptFunction("serviceworker.onPartitionData", |
+ args.get()); |
+} |
+ |
+} // namespace |
class ServiceWorkerInternalsUI::PartitionObserver |
: public ServiceWorkerContextObserver { |
@@ -209,24 +386,26 @@ ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui) |
base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations, |
base::Unretained(this))); |
web_ui->RegisterMessageCallback( |
- "start", |
- base::Bind(&ServiceWorkerInternalsUI::StartWorker, |
- base::Unretained(this))); |
- web_ui->RegisterMessageCallback( |
"stop", |
- base::Bind(&ServiceWorkerInternalsUI::StopWorker, |
+ base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod, |
+ base::Unretained(this), |
+ &ServiceWorkerVersion::StopWorker)); |
+ web_ui->RegisterMessageCallback( |
+ "sync", |
+ base::Bind(&ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod, |
+ base::Unretained(this), |
+ &ServiceWorkerVersion::DispatchSyncEvent)); |
+ web_ui->RegisterMessageCallback( |
+ "inspect", |
+ base::Bind(&ServiceWorkerInternalsUI::InspectWorker, |
base::Unretained(this))); |
web_ui->RegisterMessageCallback( |
"unregister", |
base::Bind(&ServiceWorkerInternalsUI::Unregister, |
base::Unretained(this))); |
web_ui->RegisterMessageCallback( |
- "sync", |
- base::Bind(&ServiceWorkerInternalsUI::DispatchSyncEventToWorker, |
- base::Unretained(this))); |
- web_ui->RegisterMessageCallback( |
- "inspect", |
- base::Bind(&ServiceWorkerInternalsUI::InspectWorker, |
+ "start", |
+ base::Bind(&ServiceWorkerInternalsUI::StartWorker, |
base::Unretained(this))); |
} |
@@ -243,10 +422,8 @@ ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() { |
void ServiceWorkerInternalsUI::GetAllRegistrations(const ListValue* args) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
BrowserContext* browser_context = |
web_ui()->GetWebContents()->GetBrowserContext(); |
- |
// Safe to use base::Unretained(this) because |
// ForEachStoragePartition is synchronous. |
BrowserContext::StoragePartitionCallback add_context_cb = |
@@ -274,12 +451,14 @@ void ServiceWorkerInternalsUI::AddContextFromStoragePartition( |
BrowserThread::PostTask( |
BrowserThread::IO, |
FROM_HERE, |
- base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::GetRegistrationsOnIOThread, |
- new OperationProxy(AsWeakPtr(), scoped_ptr<ListValue>()), |
- partition_id, |
- context, |
- partition->GetPath())); |
+ base::Bind(GetRegistrationsOnIOThread, |
+ context, |
+ base::Bind(OnStoredRegistrations, |
+ context, |
+ base::Bind(OnAllRegistrations, |
+ AsWeakPtr(), |
+ partition_id, |
+ partition->GetPath())))); |
} |
void ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition( |
@@ -294,406 +473,128 @@ void ServiceWorkerInternalsUI::RemoveObserverFromStoragePartition( |
context->RemoveObserver(observer.get()); |
} |
-namespace { |
-void FindContext(const base::FilePath& partition_path, |
- StoragePartition** result_partition, |
- scoped_refptr<ServiceWorkerContextWrapper>* result_context, |
- StoragePartition* storage_partition) { |
- if (storage_partition->GetPath() == partition_path) { |
+void ServiceWorkerInternalsUI::FindContext( |
+ int partition_id, |
+ StoragePartition** result_partition, |
+ StoragePartition* storage_partition) const { |
+ PartitionObserver* observer = |
+ observers_.get(reinterpret_cast<uintptr_t>(storage_partition)); |
+ if (observer && partition_id == observer->partition_id()) { |
*result_partition = storage_partition; |
- *result_context = static_cast<ServiceWorkerContextWrapper*>( |
- storage_partition->GetServiceWorkerContext()); |
} |
} |
-} // namespace |
-bool ServiceWorkerInternalsUI::GetRegistrationInfo( |
- const ListValue* args, |
- base::FilePath* partition_path, |
- GURL* scope, |
+bool ServiceWorkerInternalsUI::GetServiceWorkerContext( |
+ int partition_id, |
scoped_refptr<ServiceWorkerContextWrapper>* context) const { |
- base::FilePath::StringType path_string; |
- if (!args->GetString(0, &path_string)) |
- return false; |
- *partition_path = base::FilePath(path_string); |
- |
- std::string scope_string; |
- if (!args->GetString(1, &scope_string)) |
- return false; |
- *scope = GURL(scope_string); |
- |
BrowserContext* browser_context = |
web_ui()->GetWebContents()->GetBrowserContext(); |
- |
StoragePartition* result_partition(NULL); |
BrowserContext::StoragePartitionCallback find_context_cb = |
- base::Bind(&FindContext, *partition_path, &result_partition, context); |
+ base::Bind(&ServiceWorkerInternalsUI::FindContext, |
+ base::Unretained(this), |
+ partition_id, |
+ &result_partition); |
BrowserContext::ForEachStoragePartition(browser_context, find_context_cb); |
- |
- if (!result_partition || !(*context)) |
+ if (!result_partition) |
return false; |
- |
+ *context = static_cast<ServiceWorkerContextWrapper*>( |
+ result_partition->GetServiceWorkerContext()); |
return true; |
} |
-void ServiceWorkerInternalsUI::DispatchSyncEventToWorker( |
+void ServiceWorkerInternalsUI::CallServiceWorkerVersionMethod( |
+ ServiceWorkerVersionMethod method, |
const ListValue* args) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- base::FilePath partition_path; |
- GURL scope; |
+ int callback_id; |
+ int partition_id; |
+ int64 version_id; |
+ std::string version_id_string; |
+ const DictionaryValue* cmd_args = NULL; |
scoped_refptr<ServiceWorkerContextWrapper> context; |
- if (!GetRegistrationInfo(args, &partition_path, &scope, &context)) |
+ if (!args->GetInteger(0, &callback_id) || |
+ !args->GetDictionary(1, &cmd_args) || |
+ !cmd_args->GetInteger("partition_id", &partition_id) || |
+ !GetServiceWorkerContext(partition_id, &context) || |
+ !cmd_args->GetString("version_id", &version_id_string) || |
+ !base::StringToInt64(version_id_string, &version_id)) { |
return; |
+ } |
- scoped_ptr<ListValue> args_copy(args->DeepCopy()); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy:: |
- DispatchSyncEventToWorkerOnIOThread, |
- new OperationProxy(AsWeakPtr(), args_copy.Pass()), |
- context, |
- scope)); |
+ base::Callback<void(ServiceWorkerStatusCode)> callback = |
+ base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id); |
+ CallServiceWorkerVersionMethodWithVersionID( |
+ method, context, version_id, callback); |
} |
void ServiceWorkerInternalsUI::InspectWorker(const ListValue* args) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- base::FilePath partition_path; |
- GURL scope; |
+ int callback_id; |
+ int process_id; |
+ int devtools_agent_route_id; |
+ const DictionaryValue* cmd_args = NULL; |
scoped_refptr<ServiceWorkerContextWrapper> context; |
- if (!GetRegistrationInfo(args, &partition_path, &scope, &context)) |
+ if (!args->GetInteger(0, &callback_id) || |
+ !args->GetDictionary(1, &cmd_args) || |
+ !cmd_args->GetInteger("process_id", &process_id) || |
+ !cmd_args->GetInteger("devtools_agent_route_id", |
+ &devtools_agent_route_id)) { |
return; |
- scoped_ptr<ListValue> args_copy(args->DeepCopy()); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::InspectWorkerOnIOThread, |
- new OperationProxy(AsWeakPtr(), args_copy.Pass()), |
- context, |
- scope)); |
+ } |
+ base::Callback<void(ServiceWorkerStatusCode)> callback = |
+ base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id); |
+ scoped_refptr<DevToolsAgentHost> agent_host( |
+ EmbeddedWorkerDevToolsManager::GetInstance() |
+ ->GetDevToolsAgentHostForWorker(process_id, devtools_agent_route_id)); |
+ if (!agent_host) { |
+ callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND); |
+ return; |
+ } |
+ DevToolsManagerImpl::GetInstance()->Inspect( |
+ web_ui()->GetWebContents()->GetBrowserContext(), agent_host.get()); |
+ callback.Run(SERVICE_WORKER_OK); |
} |
void ServiceWorkerInternalsUI::Unregister(const ListValue* args) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- base::FilePath partition_path; |
- GURL scope; |
+ int callback_id; |
+ int partition_id; |
+ std::string scope_string; |
+ const DictionaryValue* cmd_args = NULL; |
scoped_refptr<ServiceWorkerContextWrapper> context; |
- if (!GetRegistrationInfo(args, &partition_path, &scope, &context)) |
+ if (!args->GetInteger(0, &callback_id) || |
+ !args->GetDictionary(1, &cmd_args) || |
+ !cmd_args->GetInteger("partition_id", &partition_id) || |
+ !GetServiceWorkerContext(partition_id, &context) || |
+ !cmd_args->GetString("scope", &scope_string)) { |
return; |
+ } |
- scoped_ptr<ListValue> args_copy(args->DeepCopy()); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::UnregisterOnIOThread, |
- new OperationProxy(AsWeakPtr(), args_copy.Pass()), |
- context, |
- scope)); |
+ base::Callback<void(ServiceWorkerStatusCode)> callback = |
+ base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id); |
+ UnregisterWithScope(context, GURL(scope_string), callback); |
} |
void ServiceWorkerInternalsUI::StartWorker(const ListValue* args) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- base::FilePath partition_path; |
- GURL scope; |
- scoped_refptr<ServiceWorkerContextWrapper> context; |
- if (!GetRegistrationInfo(args, &partition_path, &scope, &context)) |
- return; |
- |
- scoped_ptr<ListValue> args_copy(args->DeepCopy()); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::StartWorkerOnIOThread, |
- new OperationProxy(AsWeakPtr(), args_copy.Pass()), |
- context, |
- scope)); |
-} |
- |
-void ServiceWorkerInternalsUI::StopWorker(const ListValue* args) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- base::FilePath partition_path; |
- GURL scope; |
+ int callback_id; |
+ int partition_id; |
+ std::string scope_string; |
+ const DictionaryValue* cmd_args = NULL; |
scoped_refptr<ServiceWorkerContextWrapper> context; |
- if (!GetRegistrationInfo(args, &partition_path, &scope, &context)) |
- return; |
- |
- scoped_ptr<ListValue> args_copy(args->DeepCopy()); |
- BrowserThread::PostTask( |
- BrowserThread::IO, |
- FROM_HERE, |
- base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::StopWorkerOnIOThread, |
- new OperationProxy(AsWeakPtr(), args_copy.Pass()), |
- context, |
- scope)); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::GetRegistrationsOnIOThread( |
- int partition_id, |
- ServiceWorkerContextWrapper* context, |
- const base::FilePath& context_path) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- context->context()->storage()->GetAllRegistrations( |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy::OnHaveRegistrations, |
- this, |
- partition_id, |
- context_path)); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::UnregisterOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- context->context()->UnregisterServiceWorker( |
- scope, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy::OperationComplete, |
- this)); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::StartWorkerOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- // TODO(alecflett): Add support for starting/stopping workers for |
- // pending versions too. |
- context->context()->storage()->FindRegistrationForPattern( |
- scope, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy::StartActiveWorker, |
- this)); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::StopWorkerOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- // TODO(alecflett): Add support for starting/stopping workers for |
- // pending versions too. |
- context->context()->storage()->FindRegistrationForPattern( |
- scope, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy::StopActiveWorker, |
- this)); |
-} |
- |
-void |
-ServiceWorkerInternalsUI::OperationProxy::DispatchSyncEventToWorkerOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- context->context()->storage()->FindRegistrationForPattern( |
- scope, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy:: |
- DispatchSyncEventToActiveWorker, |
- this)); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::InspectWorkerOnIOThread( |
- scoped_refptr<ServiceWorkerContextWrapper> context, |
- const GURL& scope) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- context->context()->storage()->FindRegistrationForPattern( |
- scope, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy::InspectActiveWorker, |
- this, |
- context->context())); |
-} |
- |
-namespace { |
-void UpdateVersionInfo(const ServiceWorkerVersionInfo& version, |
- DictionaryValue* info) { |
- switch (version.running_status) { |
- case ServiceWorkerVersion::STOPPED: |
- info->SetString("running_status", "STOPPED"); |
- break; |
- case ServiceWorkerVersion::STARTING: |
- info->SetString("running_status", "STARTING"); |
- break; |
- case ServiceWorkerVersion::RUNNING: |
- info->SetString("running_status", "RUNNING"); |
- break; |
- case ServiceWorkerVersion::STOPPING: |
- info->SetString("running_status", "STOPPING"); |
- break; |
- } |
- |
- switch (version.status) { |
- case ServiceWorkerVersion::NEW: |
- info->SetString("status", "NEW"); |
- break; |
- case ServiceWorkerVersion::INSTALLING: |
- info->SetString("status", "INSTALLING"); |
- break; |
- case ServiceWorkerVersion::INSTALLED: |
- info->SetString("status", "INSTALLED"); |
- break; |
- case ServiceWorkerVersion::ACTIVATING: |
- info->SetString("status", "ACTIVATING"); |
- break; |
- case ServiceWorkerVersion::ACTIVE: |
- info->SetString("status", "ACTIVE"); |
- break; |
- case ServiceWorkerVersion::DEACTIVATED: |
- info->SetString("status", "DEACTIVATED"); |
- break; |
- } |
- info->SetString("version_id", base::Int64ToString(version.version_id)); |
- info->SetInteger("process_id", version.process_id); |
- info->SetInteger("thread_id", version.thread_id); |
-} |
-} // namespace |
- |
-void ServiceWorkerInternalsUI::OperationProxy::OnHaveRegistrations( |
- int partition_id, |
- const base::FilePath& context_path, |
- const std::vector<ServiceWorkerRegistrationInfo>& registrations) { |
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::OnHaveRegistrations, |
- this, |
- partition_id, |
- context_path, |
- registrations)); |
- return; |
- } |
- |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- ListValue result; |
- for (std::vector<ServiceWorkerRegistrationInfo>::const_iterator it = |
- registrations.begin(); |
- it != registrations.end(); |
- ++it) { |
- const ServiceWorkerRegistrationInfo& registration = *it; |
- DictionaryValue* registration_info = new DictionaryValue(); |
- registration_info->SetString("scope", registration.pattern.spec()); |
- registration_info->SetString("script_url", registration.script_url.spec()); |
- |
- if (!registration.active_version.is_null) { |
- DictionaryValue* active_info = new DictionaryValue(); |
- UpdateVersionInfo(registration.active_version, active_info); |
- registration_info->Set("active", active_info); |
- } |
- |
- if (!registration.pending_version.is_null) { |
- DictionaryValue* pending_info = new DictionaryValue(); |
- UpdateVersionInfo(registration.pending_version, pending_info); |
- registration_info->Set("pending", pending_info); |
- } |
- |
- result.Append(registration_info); |
- } |
- |
- if (internals_) |
- internals_->web_ui()->CallJavascriptFunction( |
- "serviceworker.onPartitionData", |
- result, |
- FundamentalValue(partition_id), |
- StringValue(context_path.value())); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::OperationComplete( |
- ServiceWorkerStatusCode status) { |
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&ServiceWorkerInternalsUI::OperationProxy::OperationComplete, |
- this, |
- status)); |
+ if (!args->GetInteger(0, &callback_id) || |
+ !args->GetDictionary(1, &cmd_args) || |
+ !cmd_args->GetInteger("partition_id", &partition_id) || |
+ !GetServiceWorkerContext(partition_id, &context) || |
+ !cmd_args->GetString("scope", &scope_string)) { |
return; |
} |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- original_args_->Insert(0, new FundamentalValue(static_cast<int>(status))); |
- if (internals_) |
- internals_->web_ui()->CallJavascriptFunction( |
- "serviceworker.onOperationComplete", |
- std::vector<const Value*>(original_args_->begin(), |
- original_args_->end())); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::StartActiveWorker( |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (status == SERVICE_WORKER_OK) { |
- registration->active_version()->StartWorker(base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::OperationComplete, this)); |
- return; |
- } |
- |
- OperationComplete(status); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::StopActiveWorker( |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (status == SERVICE_WORKER_OK) { |
- registration->active_version()->StopWorker(base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::OperationComplete, this)); |
- return; |
- } |
- |
- OperationComplete(status); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::DispatchSyncEventToActiveWorker( |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (status == SERVICE_WORKER_OK && registration->active_version() && |
- registration->active_version()->status() == |
- ServiceWorkerVersion::ACTIVE) { |
- registration->active_version()->DispatchSyncEvent(base::Bind( |
- &ServiceWorkerInternalsUI::OperationProxy::OperationComplete, this)); |
- return; |
- } |
- |
- OperationComplete(SERVICE_WORKER_ERROR_FAILED); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::InspectActiveWorker( |
- const ServiceWorkerContextCore* const service_worker_context, |
- ServiceWorkerStatusCode status, |
- const scoped_refptr<ServiceWorkerRegistration>& registration) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- if (status == SERVICE_WORKER_OK) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind(&OperationProxy::InspectWorkerOnUIThread, |
- this, |
- service_worker_context, |
- registration->active_version()->version_id())); |
- return; |
- } |
- |
- OperationComplete(status); |
-} |
- |
-void ServiceWorkerInternalsUI::OperationProxy::InspectWorkerOnUIThread( |
- const ServiceWorkerContextCore* const service_worker_context, |
- int64 version_id) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- scoped_refptr<DevToolsAgentHost> agent_host( |
- EmbeddedWorkerDevToolsManager::GetInstance() |
- ->GetDevToolsAgentHostForServiceWorker( |
- EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier( |
- service_worker_context, version_id))); |
- if (agent_host) { |
- DevToolsManagerImpl::GetInstance()->Inspect( |
- internals_->web_ui()->GetWebContents()->GetBrowserContext(), |
- agent_host.get()); |
- OperationComplete(SERVICE_WORKER_OK); |
- return; |
- } |
- OperationComplete(SERVICE_WORKER_ERROR_NOT_FOUND); |
+ base::Callback<void(ServiceWorkerStatusCode)> callback = |
+ base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id); |
+ FindRegistrationForPattern( |
+ context, GURL(scope_string), base::Bind(StartActiveWorker, callback)); |
} |
} // namespace content |