| 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..42a9a1f09cfbcf56bb1b9fbdedc650623ec870f2 100644
|
| --- a/content/browser/service_worker/service_worker_internals_ui.cc
|
| +++ b/content/browser/service_worker/service_worker_internals_ui.cc
|
| @@ -35,66 +35,240 @@ 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_;
|
| -};
|
| +void OperationCompleteCallback(WeakPtr<ServiceWorkerInternalsUI> internals,
|
| + 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) {
|
| + internals->web_ui()->CallJavascriptFunction(
|
| + "serviceworker.onOperationComplete",
|
| + FundamentalValue(static_cast<int>(status)),
|
| + FundamentalValue(callback_id));
|
| + }
|
| +}
|
| +
|
| +void CallServiceWorkerVersionMethodWithVersionID(
|
| + ServiceWorkerInternalsUI::ServiceWorkerVersionMethod method,
|
| + scoped_refptr<ServiceWorkerContextWrapper> context,
|
| + int64 version_id,
|
| + const ServiceWorkerInternalsUI::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 ServiceWorkerInternalsUI::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 ServiceWorkerInternalsUI::StatusCallback& callback,
|
| + ServiceWorkerStatusCode status) {
|
| + callback.Run(status);
|
| +}
|
| +
|
| +void StartActiveWorker(
|
| + const ServiceWorkerInternalsUI::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. If the refcount of
|
| + // |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(
|
| + WeakPtr<ServiceWorkerInternalsUI> internals,
|
| + 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 +383,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 +419,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 +448,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 +470,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
|
|
|