1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
content / browser / shared_storage / shared_storage_render_thread_worklet_driver.cc [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/shared_storage/shared_storage_render_thread_worklet_driver.h"
#include "content/browser/renderer_host/agent_scheduling_group_host.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/common/renderer.mojom.h"
#include "content/public/browser/render_process_host.h"
#include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom.h"
#include "url/origin.h"
namespace content {
SharedStorageRenderThreadWorkletDriver::SharedStorageRenderThreadWorkletDriver(
RenderFrameHost& render_frame_host,
const url::Origin& data_origin) {
StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>(
render_frame_host.GetStoragePartition());
// Leave the worklet SiteInstance as NonIsolated(), as the cross-origin
// isolated capability is currently unspecified in the spec:
// https://html.spec.whatwg.org/multipage/worklets.html#script-settings-for-worklets%3Aconcept-settings-object-cross-origin-isolated-capability
//
// TODO(yaoxia): This may need to be revisited in the future.
UrlInfo url_info(
UrlInfoInit(data_origin.GetURL())
.WithStoragePartitionConfig(storage_partition->GetConfig())
.WithWebExposedIsolationInfo(
WebExposedIsolationInfo::CreateNonIsolated()));
// We aim to approximate the process allocation behavior of iframes when
// loading a URL with origin `data_origin`.
//
// Leverage the existing process creation and tracking approach for service
// workers, with an additional call to `ReuseExistingProcessIfPossible()` that
// allows the worklet to reuse the initiator frame's process (as in Android's
// relaxed site isolation).
//
// TODO(yaoxia): Refactor into a
// `SiteInstanceImpl::CreateForSharedStorageWorklet` method. That will require
// renaming several downstream components, such as
// `UnmatchedServiceWorkerProcessTracker`.
scoped_refptr<SiteInstanceImpl> site_instance =
SiteInstanceImpl::CreateForServiceWorker(
storage_partition->browser_context(), url_info,
/*can_reuse_process=*/true, storage_partition->is_guest(),
render_frame_host.IsNestedWithinFencedFrame());
site_instance->ReuseExistingProcessIfPossible(render_frame_host.GetProcess());
// TODO(yaoxia): Gracefully handle Init() error?
site_instance->GetProcess()->Init();
site_instance->GetProcess()->AddObserver(this);
if (!site_instance->GetProcess()->AreRefCountsDisabled()) {
site_instance->GetProcess()->IncrementWorkerRefCount();
}
site_instance_ = site_instance;
}
SharedStorageRenderThreadWorkletDriver::
~SharedStorageRenderThreadWorkletDriver() {
// The render process is already destroyed. No further action is needed.
if (!site_instance_) {
return;
}
GetProcessHost()->RemoveObserver(this);
if (!GetProcessHost()->AreRefCountsDisabled()) {
GetProcessHost()->DecrementWorkerRefCount();
}
}
void SharedStorageRenderThreadWorkletDriver::StartWorkletService(
mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService>
pending_receiver,
blink::mojom::WorkletGlobalScopeCreationParamsPtr
global_scope_creation_params) {
// `StartWorkletService` will be called right after the driver is created when
// the document is still alive, as the driver is created on-demand on the
// first worklet operation. Thus, `site_instance_` should always be valid at
// this point.
DCHECK(site_instance_);
static_cast<SiteInstanceImpl&>(*site_instance_)
.GetOrCreateAgentSchedulingGroup()
.CreateSharedStorageWorkletService(
std::move(pending_receiver), std::move(global_scope_creation_params));
}
RenderProcessHost* SharedStorageRenderThreadWorkletDriver::GetProcessHost() {
if (!site_instance_) {
return nullptr;
}
return site_instance_->GetProcess();
}
void SharedStorageRenderThreadWorkletDriver::RenderProcessHostDestroyed(
RenderProcessHost* host) {
// This could occur when the browser shuts down during the worklet's
// keep-alive phase, or when the renderer process is terminated. Reset
// `site_instance_` to signal this state change. Note that calling
// GetProcessHost() again here would not return the
// original process host, so we wouldn't be able to assert `host` here.
host->RemoveObserver(this);
site_instance_ = nullptr;
}
} // namespace content