blob: c94a0146cac3d3d02c1b9edd58b178411d4e2d7c [file] [log] [blame]
/*
* Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
#include <memory>
#include <utility>
#include "third_party/blink/public/platform/modules/payments/web_payment_handler_response.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_window_client.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
namespace {
void DidNavigateOrOpenWindow(ScriptPromiseResolver* resolver,
bool success,
mojom::blink::ServiceWorkerClientInfoPtr info,
const String& error_msg) {
if (!resolver->GetExecutionContext() ||
resolver->GetExecutionContext()->IsContextDestroyed()) {
return;
}
if (!success) {
DCHECK(!info);
DCHECK(!error_msg.IsNull());
ScriptState::Scope scope(resolver->GetScriptState());
resolver->Reject(V8ThrowException::CreateTypeError(
resolver->GetScriptState()->GetIsolate(), error_msg));
return;
}
ServiceWorkerWindowClient* window_client = nullptr;
// Even if the open/navigation succeeded, |info| may be null if information of
// the opened/navigated window could not be obtained (this can happen for a
// cross-origin window, or if the browser process could not get the
// information in time before the window was closed).
if (info)
window_client = ServiceWorkerWindowClient::Create(*info);
resolver->Resolve(window_client);
}
} // namespace
ServiceWorkerGlobalScopeClient::ServiceWorkerGlobalScopeClient(
WebServiceWorkerContextClient& client)
: client_(client) {}
void ServiceWorkerGlobalScopeClient::GetClient(const String& id,
GetClientCallback callback) {
service_worker_host_->GetClient(id, std::move(callback));
}
void ServiceWorkerGlobalScopeClient::GetClients(
mojom::blink::ServiceWorkerClientQueryOptionsPtr options,
GetClientsCallback callback) {
service_worker_host_->GetClients(std::move(options), std::move(callback));
}
void ServiceWorkerGlobalScopeClient::OpenWindowForClients(
const KURL& url,
ScriptPromiseResolver* resolver) {
service_worker_host_->OpenNewTab(
url, WTF::Bind(&DidNavigateOrOpenWindow, WrapPersistent(resolver)));
}
void ServiceWorkerGlobalScopeClient::OpenWindowForPaymentHandler(
const KURL& url,
ScriptPromiseResolver* resolver) {
service_worker_host_->OpenPaymentHandlerWindow(
url, WTF::Bind(&DidNavigateOrOpenWindow, WrapPersistent(resolver)));
}
void ServiceWorkerGlobalScopeClient::SetCachedMetadata(const KURL& url,
const uint8_t* data,
size_t size) {
Vector<uint8_t> meta_data;
meta_data.Append(data, SafeCast<wtf_size_t>(size));
service_worker_host_->SetCachedMetadata(url, meta_data);
}
void ServiceWorkerGlobalScopeClient::ClearCachedMetadata(const KURL& url) {
service_worker_host_->ClearCachedMetadata(url);
}
void ServiceWorkerGlobalScopeClient::PostMessageToClient(
const String& client_uuid,
BlinkTransferableMessage message) {
service_worker_host_->PostMessageToClient(client_uuid, std::move(message));
}
void ServiceWorkerGlobalScopeClient::SkipWaiting(SkipWaitingCallback callback) {
service_worker_host_->SkipWaiting(std::move(callback));
}
void ServiceWorkerGlobalScopeClient::Claim(ClaimCallback callback) {
service_worker_host_->ClaimClients(std::move(callback));
}
void ServiceWorkerGlobalScopeClient::Focus(const String& client_uuid,
FocusCallback callback) {
service_worker_host_->FocusClient(client_uuid, std::move(callback));
}
void ServiceWorkerGlobalScopeClient::Navigate(const String& client_uuid,
const KURL& url,
ScriptPromiseResolver* resolver) {
service_worker_host_->NavigateClient(
client_uuid, url,
WTF::Bind(&DidNavigateOrOpenWindow, WrapPersistent(resolver)));
}
void ServiceWorkerGlobalScopeClient::DidHandleActivateEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleActivateEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchAbortEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleBackgroundFetchAbortEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchClickEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleBackgroundFetchClickEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchFailEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleBackgroundFetchFailEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleBackgroundFetchSuccessEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleBackgroundFetchSuccessEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleCookieChangeEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleCookieChangeEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleExtendableMessageEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleExtendableMessageEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::RespondToFetchEventWithNoResponse(
int fetch_event_id,
base::TimeTicks event_dispatch_time,
base::TimeTicks respond_with_settled_time) {
client_.RespondToFetchEventWithNoResponse(fetch_event_id, event_dispatch_time,
respond_with_settled_time);
}
void ServiceWorkerGlobalScopeClient::RespondToFetchEvent(
int fetch_event_id,
const WebServiceWorkerResponse& response,
base::TimeTicks event_dispatch_time,
base::TimeTicks respond_with_settled_time) {
client_.RespondToFetchEvent(fetch_event_id, response, event_dispatch_time,
respond_with_settled_time);
}
void ServiceWorkerGlobalScopeClient::RespondToFetchEventWithResponseStream(
int fetch_event_id,
const WebServiceWorkerResponse& response,
WebServiceWorkerStreamHandle* stream_handle,
base::TimeTicks event_dispatch_time,
base::TimeTicks respond_with_settled_time) {
client_.RespondToFetchEventWithResponseStream(
fetch_event_id, response, stream_handle, event_dispatch_time,
respond_with_settled_time);
}
void ServiceWorkerGlobalScopeClient::RespondToAbortPaymentEvent(
int event_id,
bool abort_payment) {
client_.RespondToAbortPaymentEvent(event_id, abort_payment);
}
void ServiceWorkerGlobalScopeClient::RespondToCanMakePaymentEvent(
int event_id,
bool response) {
client_.RespondToCanMakePaymentEvent(event_id, response);
}
void ServiceWorkerGlobalScopeClient::RespondToPaymentRequestEvent(
int event_id,
const WebPaymentHandlerResponse& response) {
client_.RespondToPaymentRequestEvent(event_id, response);
}
void ServiceWorkerGlobalScopeClient::DidHandleFetchEvent(
int fetch_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleFetchEvent(fetch_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleInstallEvent(
int install_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleInstallEvent(install_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleNotificationClickEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleNotificationClickEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleNotificationCloseEvent(
int event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleNotificationCloseEvent(event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandlePushEvent(
int push_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandlePushEvent(push_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleSyncEvent(
int sync_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleSyncEvent(sync_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandlePeriodicSyncEvent(
int periodic_sync_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandlePeriodicSyncEvent(periodic_sync_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleAbortPaymentEvent(
int abort_payment_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleAbortPaymentEvent(abort_payment_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandleCanMakePaymentEvent(
int payment_request_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandleCanMakePaymentEvent(payment_request_event_id, status);
}
void ServiceWorkerGlobalScopeClient::DidHandlePaymentRequestEvent(
int payment_request_event_id,
mojom::ServiceWorkerEventStatus status) {
client_.DidHandlePaymentRequestEvent(payment_request_event_id, status);
}
void ServiceWorkerGlobalScopeClient::BindServiceWorkerHost(
mojom::blink::ServiceWorkerHostAssociatedPtrInfo service_worker_host) {
DCHECK(service_worker_host.is_valid());
DCHECK(!service_worker_host_);
service_worker_host_.Bind(std::move(service_worker_host));
}
void ServiceWorkerGlobalScopeClient::WillDestroyWorkerContext() {
service_worker_host_.reset();
}
int ServiceWorkerGlobalScopeClient::WillStartTask() {
return client_.WillStartTask();
}
void ServiceWorkerGlobalScopeClient::DidEndTask(int task_id) {
client_.DidEndTask(task_id);
}
const char ServiceWorkerGlobalScopeClient::kSupplementName[] =
"ServiceWorkerGlobalScopeClient";
ServiceWorkerGlobalScopeClient* ServiceWorkerGlobalScopeClient::From(
ExecutionContext* context) {
// TODO(crbug.com/920854): Replace CHECK() with DCHECK() after crashes are
// gone.
CHECK(context);
WorkerClients* worker_clients = To<WorkerGlobalScope>(context)->Clients();
CHECK(worker_clients);
ServiceWorkerGlobalScopeClient* client =
Supplement<WorkerClients>::From<ServiceWorkerGlobalScopeClient>(
worker_clients);
CHECK(client);
return client;
}
void ServiceWorkerGlobalScopeClient::Trace(blink::Visitor* visitor) {
Supplement<WorkerClients>::Trace(visitor);
}
void ProvideServiceWorkerGlobalScopeClientToWorker(
WorkerClients* clients,
ServiceWorkerGlobalScopeClient* client) {
clients->ProvideSupplement(client);
}
} // namespace blink