| Index: content/browser/devtools/protocol/service_worker_handler.cc
|
| diff --git a/content/browser/devtools/protocol/service_worker_handler.cc b/content/browser/devtools/protocol/service_worker_handler.cc
|
| index 903705fd94c90982fd7712ee3cbf4a08639af0fa..68f05c08f01e0b08e914169631b867db7c22cdd6 100644
|
| --- a/content/browser/devtools/protocol/service_worker_handler.cc
|
| +++ b/content/browser/devtools/protocol/service_worker_handler.cc
|
| @@ -4,25 +4,282 @@
|
|
|
| #include "content/browser/devtools/protocol/service_worker_handler.h"
|
|
|
| +#include "base/bind.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "content/browser/devtools/service_worker_devtools_agent_host.h"
|
| #include "content/browser/devtools/service_worker_devtools_manager.h"
|
| +#include "content/browser/service_worker/service_worker_context_observer.h"
|
| +#include "content/browser/service_worker/service_worker_context_wrapper.h"
|
| +#include "content/public/browser/browser_context.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/devtools_agent_host.h"
|
| +#include "content/public/browser/render_frame_host.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "content/public/browser/storage_partition.h"
|
| +#include "url/gurl.h"
|
| +
|
| +// Windows headers will redefine SendMessage.
|
| +#ifdef SendMessage
|
| +#undef SendMessage
|
| +#endif
|
|
|
| namespace content {
|
| namespace devtools {
|
| namespace service_worker {
|
|
|
| +namespace {
|
| +
|
| +const std::string GetVersionRunningStatusString(
|
| + content::ServiceWorkerVersion::RunningStatus running_status) {
|
| + switch (running_status) {
|
| + case content::ServiceWorkerVersion::STOPPED:
|
| + return service_worker_version::kRunningStatusStopped;
|
| + case content::ServiceWorkerVersion::STARTING:
|
| + return service_worker_version::kRunningStatusStarting;
|
| + case content::ServiceWorkerVersion::RUNNING:
|
| + return service_worker_version::kRunningStatusRunning;
|
| + case content::ServiceWorkerVersion::STOPPING:
|
| + return service_worker_version::kRunningStatusStopping;
|
| + }
|
| + return "";
|
| +}
|
| +
|
| +const std::string GetVersionStatusString(
|
| + content::ServiceWorkerVersion::Status status) {
|
| + switch (status) {
|
| + case content::ServiceWorkerVersion::NEW:
|
| + return service_worker_version::kStatusNew;
|
| + case content::ServiceWorkerVersion::INSTALLING:
|
| + return service_worker_version::kStatusInstalling;
|
| + case content::ServiceWorkerVersion::INSTALLED:
|
| + return service_worker_version::kStatusInstalled;
|
| + case content::ServiceWorkerVersion::ACTIVATING:
|
| + return service_worker_version::kStatusActivating;
|
| + case content::ServiceWorkerVersion::ACTIVATED:
|
| + return service_worker_version::kStatusActivated;
|
| + case content::ServiceWorkerVersion::REDUNDANT:
|
| + return service_worker_version::kStatusRedundant;
|
| + }
|
| + return "";
|
| +}
|
| +
|
| +scoped_refptr<ServiceWorkerVersion> CreateVersionDictionaryValue(
|
| + const ServiceWorkerVersionInfo& version_info) {
|
| + scoped_refptr<ServiceWorkerVersion> version(
|
| + ServiceWorkerVersion::Create()
|
| + ->set_version_id(base::Int64ToString(version_info.version_id))
|
| + ->set_registration_id(
|
| + base::Int64ToString(version_info.registration_id))
|
| + ->set_script_url(version_info.script_url.spec())
|
| + ->set_running_status(
|
| + GetVersionRunningStatusString(version_info.running_status))
|
| + ->set_status(GetVersionStatusString(version_info.status)));
|
| + return version;
|
| +}
|
| +
|
| +scoped_refptr<ServiceWorkerRegistration> CreateRegistrationDictionaryValue(
|
| + const ServiceWorkerRegistrationInfo& registration_info) {
|
| + scoped_refptr<ServiceWorkerRegistration> registration(
|
| + ServiceWorkerRegistration::Create()
|
| + ->set_registration_id(
|
| + base::Int64ToString(registration_info.registration_id))
|
| + ->set_scope_url(registration_info.pattern.spec()));
|
| + if (registration_info.active_version.version_id !=
|
| + kInvalidServiceWorkerVersionId) {
|
| + registration->set_active_version(
|
| + CreateVersionDictionaryValue(registration_info.active_version));
|
| + }
|
| + if (registration_info.waiting_version.version_id !=
|
| + kInvalidServiceWorkerVersionId) {
|
| + registration->set_waiting_version(
|
| + CreateVersionDictionaryValue(registration_info.waiting_version));
|
| + }
|
| + if (registration_info.installing_version.version_id !=
|
| + kInvalidServiceWorkerVersionId) {
|
| + registration->set_installing_version(
|
| + CreateVersionDictionaryValue(registration_info.installing_version));
|
| + }
|
| + return registration;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| using Response = DevToolsProtocolClient::Response;
|
|
|
| +class ServiceWorkerHandler::ContextObserver
|
| + : public ServiceWorkerContextObserver,
|
| + public base::RefCountedThreadSafe<ContextObserver> {
|
| + public:
|
| + ContextObserver(scoped_refptr<ServiceWorkerContextWrapper> context,
|
| + base::WeakPtr<ServiceWorkerHandler> handler);
|
| + void Start();
|
| + void Stop();
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<ContextObserver>;
|
| + ~ContextObserver() override;
|
| + void GetStoredRegistrationsOnIOThread();
|
| + void OnStoredRegistrationsOnIOThread(
|
| + const std::vector<ServiceWorkerRegistrationInfo>& registrations);
|
| + void StopOnIOThread();
|
| +
|
| + void OnVersionUpdated(int64 version_id);
|
| + void OnRegistrationUpdated(int64 registration_id);
|
| +
|
| + // ServiceWorkerContextObserver implements
|
| + void OnRunningStateChanged(int64 version_id) override;
|
| + void OnVersionStateChanged(int64 version_id) override;
|
| + void OnRegistrationStored(int64 registration_id,
|
| + const GURL& pattern) override;
|
| + void OnRegistrationDeleted(int64 registration_id,
|
| + const GURL& pattern) override;
|
| +
|
| + scoped_refptr<ServiceWorkerContextWrapper> context_;
|
| + base::WeakPtr<ServiceWorkerHandler> handler_;
|
| +};
|
| +
|
| +ServiceWorkerHandler::ContextObserver::ContextObserver(
|
| + scoped_refptr<ServiceWorkerContextWrapper> context,
|
| + base::WeakPtr<ServiceWorkerHandler> handler)
|
| + : context_(context), handler_(handler) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::Start() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::ContextObserver::
|
| + GetStoredRegistrationsOnIOThread,
|
| + this));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::Stop() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::ContextObserver::StopOnIOThread, this));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::GetStoredRegistrationsOnIOThread() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + context_->context()->storage()->GetAllRegistrations(base::Bind(
|
| + &ServiceWorkerHandler::ContextObserver::OnStoredRegistrationsOnIOThread,
|
| + this));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnStoredRegistrationsOnIOThread(
|
| + const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + context_->AddObserver(this);
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_,
|
| + registrations));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_,
|
| + context_->context()->GetAllLiveRegistrationInfo()));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerVersionUpdated, handler_,
|
| + context_->context()->GetAllLiveVersionInfo()));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::StopOnIOThread() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + context_->RemoveObserver(this);
|
| +}
|
| +
|
| +ServiceWorkerHandler::ContextObserver::~ContextObserver() {
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnVersionUpdated(int64 version_id) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + content::ServiceWorkerVersion* version =
|
| + context_->context()->GetLiveVersion(version_id);
|
| + if (!version)
|
| + return;
|
| + OnRegistrationUpdated(version->registration_id());
|
| + std::vector<ServiceWorkerVersionInfo> versions;
|
| + versions.push_back(version->GetInfo());
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerVersionUpdated, handler_,
|
| + versions));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnRegistrationUpdated(
|
| + int64 registration_id) {
|
| + content::ServiceWorkerRegistration* registration =
|
| + context_->context()->GetLiveRegistration(registration_id);
|
| + if (!registration)
|
| + return;
|
| + std::vector<ServiceWorkerRegistrationInfo> registrations;
|
| + registrations.push_back(registration->GetInfo());
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_,
|
| + registrations));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnRunningStateChanged(
|
| + int64 version_id) {
|
| + OnVersionUpdated(version_id);
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnVersionStateChanged(
|
| + int64 version_id) {
|
| + OnVersionUpdated(version_id);
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnRegistrationStored(
|
| + int64 registration_id,
|
| + const GURL& pattern) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + content::ServiceWorkerRegistration* registration =
|
| + context_->context()->GetLiveRegistration(registration_id);
|
| + DCHECK(registration);
|
| + std::vector<ServiceWorkerRegistrationInfo> registrations;
|
| + registrations.push_back(registration->GetInfo());
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationUpdated, handler_,
|
| + registrations));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::ContextObserver::OnRegistrationDeleted(
|
| + int64 registration_id,
|
| + const GURL& pattern) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&ServiceWorkerHandler::OnWorkerRegistrationDeleted, handler_,
|
| + registration_id));
|
| +}
|
| +
|
| ServiceWorkerHandler::ServiceWorkerHandler()
|
| - : enabled_(false) {
|
| + : enabled_(false), weak_factory_(this) {
|
| }
|
|
|
| ServiceWorkerHandler::~ServiceWorkerHandler() {
|
| Disable();
|
| }
|
|
|
| -void ServiceWorkerHandler::SetClient(
|
| - scoped_ptr<Client> client) {
|
| +void ServiceWorkerHandler::SetRenderFrameHost(
|
| + RenderFrameHost* render_frame_host) {
|
| + if (!render_frame_host) {
|
| + context_ = nullptr;
|
| + return;
|
| + }
|
| + StoragePartition* partition = BrowserContext::GetStoragePartition(
|
| + render_frame_host->GetProcess()->GetBrowserContext(),
|
| + render_frame_host->GetSiteInstance());
|
| + DCHECK(partition);
|
| + context_ = static_cast<ServiceWorkerContextWrapper*>(
|
| + partition->GetServiceWorkerContext());
|
| +}
|
| +
|
| +void ServiceWorkerHandler::SetClient(scoped_ptr<Client> client) {
|
| client_.swap(client);
|
| }
|
|
|
| @@ -57,6 +314,8 @@ void ServiceWorkerHandler::Detached() {
|
| Response ServiceWorkerHandler::Enable() {
|
| if (enabled_)
|
| return Response::OK();
|
| + if (!context_)
|
| + return Response::InternalError("Could not connect to the context");
|
| enabled_ = true;
|
|
|
| ServiceWorkerDevToolsManager::GetInstance()->AddObserver(this);
|
| @@ -65,6 +324,9 @@ Response ServiceWorkerHandler::Enable() {
|
| ServiceWorkerDevToolsManager::GetInstance()->AddAllAgentHosts(&agent_hosts);
|
| for (auto host : agent_hosts)
|
| WorkerReadyForInspection(host.get());
|
| +
|
| + context_observer_ = new ContextObserver(context_, weak_factory_.GetWeakPtr());
|
| + context_observer_->Start();
|
| return Response::OK();
|
| }
|
|
|
| @@ -77,6 +339,9 @@ Response ServiceWorkerHandler::Disable() {
|
| for (const auto& pair : attached_hosts_)
|
| pair.second->DetachClient();
|
| attached_hosts_.clear();
|
| + DCHECK(context_observer_);
|
| + context_observer_->Stop();
|
| + context_observer_ = nullptr;
|
| return Response::OK();
|
| }
|
|
|
| @@ -99,6 +364,34 @@ Response ServiceWorkerHandler::Stop(
|
| return Response::OK();
|
| }
|
|
|
| +void ServiceWorkerHandler::OnWorkerRegistrationUpdated(
|
| + const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
|
| + std::vector<scoped_refptr<ServiceWorkerRegistration>> registration_values;
|
| + for (const auto& registration : registrations) {
|
| + registration_values.push_back(
|
| + CreateRegistrationDictionaryValue(registration));
|
| + }
|
| + client_->WorkerRegistrationUpdated(
|
| + WorkerRegistrationUpdatedParams::Create()->set_registrations(
|
| + registration_values));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::OnWorkerVersionUpdated(
|
| + const std::vector<ServiceWorkerVersionInfo>& versions) {
|
| + std::vector<scoped_refptr<ServiceWorkerVersion>> version_values;
|
| + for (const auto& version : versions) {
|
| + version_values.push_back(CreateVersionDictionaryValue(version));
|
| + }
|
| + client_->WorkerVersionUpdated(
|
| + WorkerVersionUpdatedParams::Create()->set_versions(version_values));
|
| +}
|
| +
|
| +void ServiceWorkerHandler::OnWorkerRegistrationDeleted(int64 registration_id) {
|
| + client_->WorkerRegistrationDeleted(
|
| + WorkerRegistrationDeletedParams::Create()->set_registration_id(
|
| + base::Int64ToString(registration_id)));
|
| +}
|
| +
|
| void ServiceWorkerHandler::DispatchProtocolMessage(
|
| DevToolsAgentHost* host,
|
| const std::string& message) {
|
|
|