blob: 77f7f2006b5d9b9ccf529ed7e35e83ee77df03e9 [file] [log] [blame]
// Copyright 2013 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/browser/service_worker/service_worker_host.h"
#include <utility>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/task/post_task.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/service_worker/service_worker_consts.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/webtransport/web_transport_connector_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/origin_util.h"
#include "mojo/public/cpp/bindings/message.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
namespace content {
namespace {
void CreateWebTransportConnectorImpl(
int process_id,
const url::Origin& origin,
const net::NetworkIsolationKey& network_isolation_key,
mojo::PendingReceiver<blink::mojom::WebTransportConnector> receiver) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto* process = RenderProcessHost::FromID(process_id);
if (!process)
return;
mojo::MakeSelfOwnedReceiver(
std::make_unique<WebTransportConnectorImpl>(
process_id, /*frame=*/nullptr, origin, network_isolation_key),
std::move(receiver));
}
} // anonymous namespace
ServiceWorkerHost::ServiceWorkerHost(
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver,
ServiceWorkerVersion* version,
base::WeakPtr<ServiceWorkerContextCore> context)
: version_(version),
container_host_(std::make_unique<content::ServiceWorkerContainerHost>(
std::move(context))),
host_receiver_(container_host_.get(), std::move(host_receiver)) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(version_);
container_host_->set_service_worker_host(this);
container_host_->UpdateUrls(
version_->script_url(),
net::SiteForCookies::FromUrl(version_->script_url()), version_->origin());
}
ServiceWorkerHost::~ServiceWorkerHost() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
// Explicitly destroy the ServiceWorkerContainerHost to release
// ServiceWorkerObjectHosts and ServiceWorkerRegistrationObjectHosts owned by
// that. Otherwise, this destructor can trigger their Mojo connection error
// handlers, which would call back into halfway destroyed |this|. This is
// because they are associated with the ServiceWorker interface, which can be
// destroyed while in this destructor (|version_|'s |event_dispatcher_|).
// See https://crbug.com/854993.
container_host_.reset();
}
void ServiceWorkerHost::CompleteStartWorkerPreparation(
int process_id,
mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
broker_receiver) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, worker_process_id_);
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
worker_process_id_ = process_id;
broker_receiver_.Bind(std::move(broker_receiver));
}
void ServiceWorkerHost::CreateWebTransportConnector(
mojo::PendingReceiver<blink::mojom::WebTransportConnector> receiver) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(&CreateWebTransportConnectorImpl, worker_process_id_,
version_->origin(), GetNetworkIsolationKey(),
std::move(receiver)));
}
void ServiceWorkerHost::BindCacheStorage(
mojo::PendingReceiver<blink::mojom::CacheStorage> receiver) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(!base::FeatureList::IsEnabled(
blink::features::kEagerCacheStorageSetupForServiceWorkers));
version_->embedded_worker()->BindCacheStorage(std::move(receiver));
}
net::NetworkIsolationKey ServiceWorkerHost::GetNetworkIsolationKey() const {
// TODO(https://crbug.com/1147281): This is the NetworkIsolationKey of a
// top-level browsing context, which shouldn't be use for ServiceWorkers used
// in iframes.
return net::NetworkIsolationKey::ToDoUseTopFrameOriginAsWell(
version_->origin());
}
base::WeakPtr<ServiceWorkerHost> ServiceWorkerHost::GetWeakPtr() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
return weak_factory_.GetWeakPtr();
}
void ServiceWorkerHost::ReportNoBinderForInterface(const std::string& error) {
broker_receiver_.ReportBadMessage(error + " for the service worker scope");
}
} // namespace content