Chromium Code Reviews| 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 |