blob: 187f062def903f7de47a067803175b44cbbcaf6d [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_provider_host.h"
#include <utility>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/task/post_task.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/interface_provider_filtering.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/quic_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/messaging/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
namespace content {
namespace {
// This function provides the next ServiceWorkerProviderHost ID.
int NextProviderId() {
static int g_next_provider_id = 0;
return g_next_provider_id++;
}
void CreateQuicTransportConnectorImpl(
int process_id,
const url::Origin& origin,
mojo::PendingReceiver<blink::mojom::QuicTransportConnector> receiver) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto* process = RenderProcessHost::FromID(process_id);
if (!process)
return;
mojo::MakeSelfOwnedReceiver(
std::make_unique<QuicTransportConnectorImpl>(
process_id, origin, net::NetworkIsolationKey(origin, origin)),
std::move(receiver));
}
} // anonymous namespace
ServiceWorkerProviderHost::ServiceWorkerProviderHost(
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver,
scoped_refptr<ServiceWorkerVersion> running_hosted_version,
base::WeakPtr<ServiceWorkerContextCore> context)
: provider_id_(NextProviderId()),
running_hosted_version_(std::move(running_hosted_version)),
container_host_(std::make_unique<content::ServiceWorkerContainerHost>(
blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
/*is_parent_frame_secure=*/true,
FrameTreeNode::kFrameTreeNodeInvalidId,
std::move(host_receiver),
mojo::NullAssociatedRemote(),
context)) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(running_hosted_version_);
container_host_->set_service_worker_host(this);
container_host_->UpdateUrls(
running_hosted_version_->script_url(),
net::SiteForCookies::FromUrl(running_hosted_version_->script_url()),
running_hosted_version_->script_origin());
}
ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
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 (|running_hosted_version_|'s
// |event_dispatcher_|). See https://crbug.com/854993.
container_host_.reset();
}
ServiceWorkerVersion* ServiceWorkerProviderHost::running_hosted_version()
const {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(running_hosted_version_);
return running_hosted_version_.get();
}
void ServiceWorkerProviderHost::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 ServiceWorkerProviderHost::CreateQuicTransportConnector(
mojo::PendingReceiver<blink::mojom::QuicTransportConnector> receiver) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(&CreateQuicTransportConnectorImpl, worker_process_id_,
running_hosted_version_->script_origin(),
std::move(receiver)));
}
base::WeakPtr<ServiceWorkerProviderHost>
ServiceWorkerProviderHost::GetWeakPtr() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
return weak_factory_.GetWeakPtr();
}
} // namespace content