blob: 48d440e40c3eaa4614c84b9ed1fff8fc3b700208 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include <utility>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/service_worker/service_worker_registration_handle_reference.h"
#include "content/child/service_worker/web_service_worker_impl.h"
#include "content/child/service_worker/web_service_worker_provider_impl.h"
#include "content/common/service_worker/service_worker_types.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebNavigationPreloadState.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistrationProxy.h"
namespace content {
namespace {
class HandleImpl : public blink::WebServiceWorkerRegistration::Handle {
public:
explicit HandleImpl(
const scoped_refptr<WebServiceWorkerRegistrationImpl>& registration)
: registration_(registration) {}
~HandleImpl() override {}
blink::WebServiceWorkerRegistration* registration() override {
return registration_.get();
}
private:
scoped_refptr<WebServiceWorkerRegistrationImpl> registration_;
DISALLOW_COPY_AND_ASSIGN(HandleImpl);
};
} // namespace
WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
QueuedTaskType type,
const scoped_refptr<WebServiceWorkerImpl>& worker)
: type(type), worker(worker) {}
WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
const QueuedTask& other) = default;
WebServiceWorkerRegistrationImpl::QueuedTask::~QueuedTask() {}
WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl(
std::unique_ptr<ServiceWorkerRegistrationHandleReference> handle_ref)
: handle_ref_(std::move(handle_ref)), proxy_(nullptr) {
DCHECK(handle_ref_);
DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId,
handle_ref_->handle_id());
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->AddServiceWorkerRegistration(handle_ref_->handle_id(), this);
}
void WebServiceWorkerRegistrationImpl::SetInstalling(
const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
if (proxy_)
proxy_->setInstalling(WebServiceWorkerImpl::CreateHandle(service_worker));
else
queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker));
}
void WebServiceWorkerRegistrationImpl::SetWaiting(
const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
if (proxy_)
proxy_->setWaiting(WebServiceWorkerImpl::CreateHandle(service_worker));
else
queued_tasks_.push_back(QueuedTask(WAITING, service_worker));
}
void WebServiceWorkerRegistrationImpl::SetActive(
const scoped_refptr<WebServiceWorkerImpl>& service_worker) {
if (proxy_)
proxy_->setActive(WebServiceWorkerImpl::CreateHandle(service_worker));
else
queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker));
}
void WebServiceWorkerRegistrationImpl::OnUpdateFound() {
if (proxy_)
proxy_->dispatchUpdateFoundEvent();
else
queued_tasks_.push_back(QueuedTask(UPDATE_FOUND, nullptr));
}
void WebServiceWorkerRegistrationImpl::setProxy(
blink::WebServiceWorkerRegistrationProxy* proxy) {
proxy_ = proxy;
RunQueuedTasks();
}
void WebServiceWorkerRegistrationImpl::RunQueuedTasks() {
DCHECK(proxy_);
for (const QueuedTask& task : queued_tasks_) {
if (task.type == INSTALLING)
proxy_->setInstalling(WebServiceWorkerImpl::CreateHandle(task.worker));
else if (task.type == WAITING)
proxy_->setWaiting(WebServiceWorkerImpl::CreateHandle(task.worker));
else if (task.type == ACTIVE)
proxy_->setActive(WebServiceWorkerImpl::CreateHandle(task.worker));
else if (task.type == UPDATE_FOUND)
proxy_->dispatchUpdateFoundEvent();
}
queued_tasks_.clear();
}
blink::WebServiceWorkerRegistrationProxy*
WebServiceWorkerRegistrationImpl::proxy() {
return proxy_;
}
blink::WebURL WebServiceWorkerRegistrationImpl::scope() const {
return handle_ref_->scope();
}
void WebServiceWorkerRegistrationImpl::update(
blink::WebServiceWorkerProvider* provider,
std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) {
WebServiceWorkerProviderImpl* provider_impl =
static_cast<WebServiceWorkerProviderImpl*>(provider);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->UpdateServiceWorker(provider_impl->provider_id(),
registrationId(), std::move(callbacks));
}
void WebServiceWorkerRegistrationImpl::unregister(
blink::WebServiceWorkerProvider* provider,
std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) {
WebServiceWorkerProviderImpl* provider_impl =
static_cast<WebServiceWorkerProviderImpl*>(provider);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->UnregisterServiceWorker(provider_impl->provider_id(),
registrationId(), std::move(callbacks));
}
void WebServiceWorkerRegistrationImpl::enableNavigationPreload(
bool enable,
blink::WebServiceWorkerProvider* provider,
std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) {
WebServiceWorkerProviderImpl* provider_impl =
static_cast<WebServiceWorkerProviderImpl*>(provider);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->EnableNavigationPreload(provider_impl->provider_id(),
registrationId(), enable,
std::move(callbacks));
}
void WebServiceWorkerRegistrationImpl::getNavigationPreloadState(
blink::WebServiceWorkerProvider* provider,
std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) {
WebServiceWorkerProviderImpl* provider_impl =
static_cast<WebServiceWorkerProviderImpl*>(provider);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->GetNavigationPreloadState(provider_impl->provider_id(),
registrationId(), std::move(callbacks));
}
void WebServiceWorkerRegistrationImpl::setNavigationPreloadHeader(
const blink::WebString& value,
blink::WebServiceWorkerProvider* provider,
std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) {
WebServiceWorkerProviderImpl* provider_impl =
static_cast<WebServiceWorkerProviderImpl*>(provider);
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->SetNavigationPreloadHeader(provider_impl->provider_id(),
registrationId(), value.utf8(),
std::move(callbacks));
}
int64_t WebServiceWorkerRegistrationImpl::registrationId() const {
return handle_ref_->registration_id();
}
// static
std::unique_ptr<blink::WebServiceWorkerRegistration::Handle>
WebServiceWorkerRegistrationImpl::CreateHandle(
const scoped_refptr<WebServiceWorkerRegistrationImpl>& registration) {
if (!registration)
return nullptr;
return base::MakeUnique<HandleImpl>(registration);
}
blink::WebServiceWorkerRegistration::Handle*
WebServiceWorkerRegistrationImpl::CreateLeakyHandle(
const scoped_refptr<WebServiceWorkerRegistrationImpl>& registration) {
if (!registration)
return nullptr;
return new HandleImpl(registration);
}
WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() {
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
if (dispatcher)
dispatcher->RemoveServiceWorkerRegistration(handle_ref_->handle_id());
}
} // namespace content