blob: dafe536d7beffed5c2137518df6d594412a1be19 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2021 The Chromium Authors
Harkiran Bolaria8dec6f92021-12-07 14:57:122// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/renderer_host/browsing_context_state.h"
6
David Sanders27d32052022-04-04 18:08:197#include "base/memory/ptr_util.h"
Harkiran Bolaria2912a6b32022-02-22 16:43:458#include "content/browser/renderer_host/frame_tree_node.h"
Harkiran Bolaria3f83fba72022-03-10 17:48:409#include "content/browser/renderer_host/render_frame_host_impl.h"
Harkiran Bolaria2912a6b32022-02-22 16:43:4510#include "content/browser/renderer_host/render_view_host_impl.h"
Charlie Reis37be2682023-01-10 17:04:4711#include "content/browser/site_instance_impl.h"
Harkiran Bolaria2912a6b32022-02-22 16:43:4512#include "content/common/content_navigation_policy.h"
Harkiran Bolaria5ce27632022-01-20 15:05:0513#include "services/network/public/cpp/web_sandbox_flags.h"
14#include "services/network/public/mojom/web_sandbox_flags.mojom.h"
15
Harkiran Bolaria8dec6f92021-12-07 14:57:1216namespace features {
Daniel Cheng0abd9f32022-09-22 04:20:1117BASE_FEATURE(kNewBrowsingContextStateOnBrowsingContextGroupSwap,
18 "NewBrowsingContextStateOnBrowsingContextGroupSwap",
19 base::FEATURE_DISABLED_BY_DEFAULT);
Harkiran Bolaria8dec6f92021-12-07 14:57:1220
21BrowsingContextStateImplementationType GetBrowsingContextMode() {
22 if (base::FeatureList::IsEnabled(
23 kNewBrowsingContextStateOnBrowsingContextGroupSwap)) {
24 return BrowsingContextStateImplementationType::
25 kSwapForCrossBrowsingInstanceNavigations;
26 }
27
28 return BrowsingContextStateImplementationType::
29 kLegacyOneToOneWithFrameTreeNode;
30}
31} // namespace features
32
33namespace content {
34
Harkiran Bolariaa8347782022-04-06 09:25:1135using perfetto::protos::pbzero::ChromeTrackEvent;
36
Harkiran Bolaria4eacb3a2021-12-13 20:03:4737BrowsingContextState::BrowsingContextState(
Harkiran Bolaria880a7632022-02-28 16:02:5038 blink::mojom::FrameReplicationStatePtr replication_state,
Arthur Sonzogni91fd79b2023-04-19 15:37:1439 RenderFrameHostImpl* parent,
Arthur Sonzognic686e8f2024-01-11 08:36:3740 std::optional<BrowsingInstanceId> browsing_instance_id,
41 std::optional<base::UnguessableToken> coop_related_group_token)
Harkiran Bolaria0b3bdef02022-03-10 13:04:4042 : replication_state_(std::move(replication_state)),
43 parent_(parent),
Arthur Hemery08d82882023-04-27 12:33:1444 browsing_instance_id_(browsing_instance_id),
Arthur Hemerya3e593f2023-05-11 17:15:5745 coop_related_group_token_(coop_related_group_token) {
Harkiran Bolariaa8347782022-04-06 09:25:1146 TRACE_EVENT_BEGIN("navigation", "BrowsingContextState",
47 perfetto::Track::FromPointer(this),
48 "browsing_context_state_when_created", this);
49}
Harkiran Bolaria8dec6f92021-12-07 14:57:1250
Harkiran Bolariaa8347782022-04-06 09:25:1151BrowsingContextState::~BrowsingContextState() {
52 TRACE_EVENT_END("navigation", perfetto::Track::FromPointer(this));
W. James MacLean0fbe7dc52023-08-22 20:20:4853 CHECK(proxy_hosts_.empty());
Harkiran Bolariaa8347782022-04-06 09:25:1154}
Harkiran Bolaria4eacb3a2021-12-13 20:03:4755
Harkiran Bolaria5ce27632022-01-20 15:05:0556RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:0157 SiteInstanceGroup* site_instance_group,
58 ProxyAccessMode proxy_access_mode) const {
Peilin Wang9791d802023-05-09 19:07:3159 TRACE_EVENT_BEGIN("navigation.debug",
Harkiran Bolariaa8347782022-04-06 09:25:1160 "BrowsingContextState::GetRenderFrameProxyHost",
61 ChromeTrackEvent::kBrowsingContextState, this,
62 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group);
Harkiran Bolariae45272d2022-04-12 08:05:0163 auto* proxy =
64 GetRenderFrameProxyHostImpl(site_instance_group, proxy_access_mode);
Peilin Wang9791d802023-05-09 19:07:3165 TRACE_EVENT_END("navigation.debug", ChromeTrackEvent::kRenderFrameProxyHost,
66 proxy);
Harkiran Bolariaa8347782022-04-06 09:25:1167 return proxy;
68}
69
70RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHostImpl(
Harkiran Bolariae45272d2022-04-12 08:05:0171 SiteInstanceGroup* site_instance_group,
72 ProxyAccessMode proxy_access_mode) const {
Harkiran Bolaria5c5a97392022-03-10 14:18:5073 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:0174 features::BrowsingContextStateImplementationType::
75 kSwapForCrossBrowsingInstanceNavigations &&
76 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:5077 // CHECK to verify that the proxy is being accessed from the correct
78 // BrowsingContextState. As both BrowsingContextState (in non-legacy mode)
79 // and RenderFrameProxyHost (via SiteInstance) are tied to a given
Arthur Hemery08d82882023-04-27 12:33:1480 // CoopRelatedGroup, the CoopRelatedGroupId of the BrowsingContextState
81 // (in the non-legacy mode) and of the SiteInstanceGroup should match. If
82 // they do not, the code calling this method has likely chosen the wrong
83 // BrowsingContextState (e.g. one from the current RenderFrameHost rather
84 // than from speculative or vice versa) – as this can lead to various
85 // unpredictable bugs in proxy management logic, we want to crash the
86 // browser here when this condition fails.
Harkiran Bolaria5c5a97392022-03-10 14:18:5087 //
Arthur Hemery08d82882023-04-27 12:33:1488 // Note: Outer delegates are an exception, and when we're expecting to
89 // interact with one, we should pass in the proper `proxy_access_mode` to
90 // not end up in this condition.
Arthur Hemerya3e593f2023-05-11 17:15:5791 CHECK_EQ(coop_related_group_token_.value(),
92 site_instance_group->coop_related_group_token());
Harkiran Bolaria5c5a97392022-03-10 14:18:5093 }
Harkiran Bolaria5ce27632022-01-20 15:05:0594 auto it = proxy_hosts_.find(site_instance_group->GetId());
Harkiran Bolariaa8347782022-04-06 09:25:1195 if (it != proxy_hosts_.end()) {
Harkiran Bolaria5ce27632022-01-20 15:05:0596 return it->second.get();
Harkiran Bolariaa8347782022-04-06 09:25:1197 }
Harkiran Bolaria5ce27632022-01-20 15:05:0598 return nullptr;
99}
100
Harkiran Bolaria5c5a97392022-03-10 14:18:50101void BrowsingContextState::DeleteRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:01102 SiteInstanceGroup* site_instance_group,
103 ProxyAccessMode proxy_access_mode) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50104 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:01105 features::BrowsingContextStateImplementationType::
106 kSwapForCrossBrowsingInstanceNavigations &&
107 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50108 // See comments in GetRenderFrameProxyHost for why this check is needed.
Arthur Hemerya3e593f2023-05-11 17:15:57109 CHECK_EQ(coop_related_group_token_.value(),
110 site_instance_group->coop_related_group_token());
Harkiran Bolaria5c5a97392022-03-10 14:18:50111 }
Harkiran Bolariaa8347782022-04-06 09:25:11112 TRACE_EVENT("navigation", "BrowsingContextState::DeleteRenderFrameProxyHost",
113 ChromeTrackEvent::kBrowsingContextState, this,
114 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group);
Harkiran Bolaria5c5a97392022-03-10 14:18:50115 site_instance_group->RemoveObserver(this);
116 proxy_hosts_.erase(site_instance_group->GetId());
117}
118
119RenderFrameProxyHost* BrowsingContextState::CreateRenderFrameProxyHost(
Charlie Reis37be2682023-01-10 17:04:47120 SiteInstanceImpl* site_instance,
Harkiran Bolaria5c5a97392022-03-10 14:18:50121 const scoped_refptr<RenderViewHostImpl>& rvh,
Harkiran Bolariae45272d2022-04-12 08:05:01122 FrameTreeNode* frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27123 ProxyAccessMode proxy_access_mode,
124 const blink::RemoteFrameToken& frame_token) {
Harkiran Bolariaa8347782022-04-06 09:25:11125 TRACE_EVENT_BEGIN(
126 "navigation", "BrowsingContextState::CreateRenderFrameProxyHost",
127 ChromeTrackEvent::kBrowsingContextState, this,
Charlie Reis37be2682023-01-10 17:04:47128 ChromeTrackEvent::kSiteInstanceGroup, site_instance->group(),
Harkiran Bolariaa8347782022-04-06 09:25:11129 ChromeTrackEvent::kRenderViewHost, rvh ? rvh.get() : nullptr,
130 ChromeTrackEvent::kFrameTreeNodeInfo, frame_tree_node);
131
Harkiran Bolaria5c5a97392022-03-10 14:18:50132 if (features::GetBrowsingContextMode() ==
133 features::BrowsingContextStateImplementationType::
134 kLegacyOneToOneWithFrameTreeNode) {
135 DCHECK_EQ(this,
136 frame_tree_node->current_frame_host()->browsing_context_state());
137 }
138
139 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:01140 features::BrowsingContextStateImplementationType::
141 kSwapForCrossBrowsingInstanceNavigations &&
142 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50143 // See comments in GetRenderFrameProxyHost for why this check is needed.
Arthur Hemerya3e593f2023-05-11 17:15:57144 CHECK_EQ(coop_related_group_token_.value(),
145 site_instance->coop_related_group_token());
Harkiran Bolaria5c5a97392022-03-10 14:18:50146 }
147
Charlie Reis37be2682023-01-10 17:04:47148 auto site_instance_group_id = site_instance->group()->GetId();
Harkiran Bolaria5c5a97392022-03-10 14:18:50149 CHECK(proxy_hosts_.find(site_instance_group_id) == proxy_hosts_.end())
150 << "A proxy already existed for this SiteInstanceGroup.";
Dave Tapuska144570102022-08-02 19:28:27151 RenderFrameProxyHost* proxy_host = new RenderFrameProxyHost(
152 site_instance, std::move(rvh), frame_tree_node, frame_token);
Harkiran Bolaria5c5a97392022-03-10 14:18:50153 proxy_hosts_[site_instance_group_id] = base::WrapUnique(proxy_host);
Charlie Reis37be2682023-01-10 17:04:47154 site_instance->group()->AddObserver(this);
Harkiran Bolaria5c5a97392022-03-10 14:18:50155
Harkiran Bolariaa8347782022-04-06 09:25:11156 TRACE_EVENT_END("navigation", ChromeTrackEvent::kRenderFrameProxyHost,
157 proxy_host);
Harkiran Bolaria5c5a97392022-03-10 14:18:50158 return proxy_host;
159}
160
Harkiran Bolariae45272d2022-04-12 08:05:01161RenderFrameProxyHost* BrowsingContextState::CreateOuterDelegateProxy(
Charlie Reis37be2682023-01-10 17:04:47162 SiteInstanceImpl* outer_contents_site_instance,
Dave Tapuska144570102022-08-02 19:28:27163 FrameTreeNode* frame_tree_node,
164 const blink::RemoteFrameToken& frame_token) {
Harkiran Bolariae45272d2022-04-12 08:05:01165 // We only get here when Delegate for this manager is an inner delegate.
166 return CreateRenderFrameProxyHost(outer_contents_site_instance,
167 /*rvh=*/nullptr, frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27168 ProxyAccessMode::kAllowOuterDelegate,
169 frame_token);
Harkiran Bolariae45272d2022-04-12 08:05:01170}
171
172void BrowsingContextState::DeleteOuterDelegateProxy(
173 SiteInstanceGroup* outer_contents_site_instance_group) {
174 DeleteRenderFrameProxyHost(
175 outer_contents_site_instance_group,
176 BrowsingContextState::ProxyAccessMode::kAllowOuterDelegate);
177}
178
Harkiran Bolariad22a1dca2022-02-22 17:01:12179size_t BrowsingContextState::GetProxyCount() {
180 return proxy_hosts_.size();
181}
182
Harkiran Bolaria5ce27632022-01-20 15:05:05183bool BrowsingContextState::UpdateFramePolicyHeaders(
184 network::mojom::WebSandboxFlags sandbox_flags,
185 const blink::ParsedPermissionsPolicy& parsed_header) {
186 bool changed = false;
187 if (replication_state_->permissions_policy_header != parsed_header) {
188 replication_state_->permissions_policy_header = parsed_header;
189 changed = true;
190 }
191 // TODO(iclelland): Kill the renderer if sandbox flags is not a subset of the
192 // currently effective sandbox flags from the frame. https://crbug.com/740556
193 network::mojom::WebSandboxFlags updated_flags =
194 sandbox_flags | replication_state_->frame_policy.sandbox_flags;
195 if (replication_state_->active_sandbox_flags != updated_flags) {
196 replication_state_->active_sandbox_flags = updated_flags;
197 changed = true;
198 }
199 // Notify any proxies if the policies have been changed.
200 if (changed) {
Dave Tapuska82b54012022-07-15 23:26:10201 ExecuteRemoteFramesBroadcastMethod(
202 base::BindRepeating(
203 [](blink::mojom::FrameReplicationStatePtr& replication_state,
204 RenderFrameProxyHost* proxy) {
205 proxy->GetAssociatedRemoteFrame()->DidSetFramePolicyHeaders(
206 replication_state->active_sandbox_flags,
207 replication_state->permissions_policy_header);
208 },
209 std::ref(replication_state_)),
Sharon Yang6b5313432023-03-24 05:07:57210 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria5ce27632022-01-20 15:05:05211 }
212 return changed;
213}
214
215bool BrowsingContextState::CommitFramePolicy(
216 const blink::FramePolicy& new_frame_policy) {
217 // Documents create iframes, iframes host new documents. Both are associated
218 // with sandbox flags. They are required to be stricter or equal to their
219 // owner when they change, as we go down.
Alison Gale81f4f2c72024-04-22 19:33:31220 // TODO(crbug.com/40202483). Enforce the invariant mentioned above,
Harkiran Bolaria5ce27632022-01-20 15:05:05221 // once the interactions with fenced frame has been tested and clarified.
222
223 bool did_change_flags = new_frame_policy.sandbox_flags !=
224 replication_state_->frame_policy.sandbox_flags;
225 bool did_change_container_policy =
226 new_frame_policy.container_policy !=
227 replication_state_->frame_policy.container_policy;
228 bool did_change_required_document_policy =
229 new_frame_policy.required_document_policy !=
230 replication_state_->frame_policy.required_document_policy;
Harkiran Bolaria5ce27632022-01-20 15:05:05231
Harkiran Bolaria4eacb3a2021-12-13 20:03:47232 if (did_change_flags) {
233 replication_state_->frame_policy.sandbox_flags =
234 new_frame_policy.sandbox_flags;
235 }
236 if (did_change_container_policy) {
237 replication_state_->frame_policy.container_policy =
238 new_frame_policy.container_policy;
239 }
240 if (did_change_required_document_policy) {
241 replication_state_->frame_policy.required_document_policy =
242 new_frame_policy.required_document_policy;
243 }
Harkiran Bolariae3521432021-12-14 11:27:43244
Harkiran Bolaria5ce27632022-01-20 15:05:05245 UpdateFramePolicyHeaders(new_frame_policy.sandbox_flags,
246 replication_state_->permissions_policy_header);
247 return did_change_flags || did_change_container_policy ||
248 did_change_required_document_policy;
Harkiran Bolaria7fdb4c642021-12-20 12:47:00249}
250
Harkiran Bolaria880a7632022-02-28 16:02:50251void BrowsingContextState::SetFrameName(const std::string& name,
252 const std::string& unique_name) {
253 if (name == replication_state_->name) {
254 // |unique_name| shouldn't change unless |name| changes.
255 DCHECK_EQ(unique_name, replication_state_->unique_name);
256 return;
257 }
258
259 if (parent_) {
260 // Non-main frames should have a non-empty unique name.
261 DCHECK(!unique_name.empty());
262 } else {
263 // Unique name of main frames should always stay empty.
264 DCHECK(unique_name.empty());
265 }
266
267 // Note the unique name should only be able to change before the first real
268 // load is committed, but that's not strongly enforced here.
Dave Tapuska82b54012022-07-15 23:26:10269 ExecuteRemoteFramesBroadcastMethod(
270 base::BindRepeating(
271 [](const std::string& name, const std::string& unique_name,
272 RenderFrameProxyHost* proxy) {
273 proxy->GetAssociatedRemoteFrame()->SetReplicatedName(name,
274 unique_name);
275 },
276 std::ref(name), std::ref(unique_name)),
Sharon Yang6b5313432023-03-24 05:07:57277 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria880a7632022-02-28 16:02:50278 replication_state_->unique_name = unique_name;
279 replication_state_->name = name;
280}
281
Harkiran Bolariae3521432021-12-14 11:27:43282void BrowsingContextState::SetCurrentOrigin(
283 const url::Origin& origin,
284 bool is_potentially_trustworthy_unique_origin) {
285 if (origin.IsSameOriginWith(replication_state_->origin) &&
286 replication_state_->has_potentially_trustworthy_unique_origin ==
287 is_potentially_trustworthy_unique_origin) {
288 return;
289 }
290
Dave Tapuska82b54012022-07-15 23:26:10291 ExecuteRemoteFramesBroadcastMethod(
292 base::BindRepeating(
293 [](const url::Origin& origin,
294 bool is_potentially_trustworthy_unique_origin,
295 RenderFrameProxyHost* proxy) {
296 proxy->GetAssociatedRemoteFrame()->SetReplicatedOrigin(
297 origin, is_potentially_trustworthy_unique_origin);
298 },
299 std::ref(origin), std::ref(is_potentially_trustworthy_unique_origin)),
Sharon Yang6b5313432023-03-24 05:07:57300 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolariae3521432021-12-14 11:27:43301
302 replication_state_->origin = origin;
303 replication_state_->has_potentially_trustworthy_unique_origin =
304 is_potentially_trustworthy_unique_origin;
305}
306
307void BrowsingContextState::SetInsecureRequestPolicy(
308 blink::mojom::InsecureRequestPolicy policy) {
309 if (policy == replication_state_->insecure_request_policy)
310 return;
Dave Tapuska82b54012022-07-15 23:26:10311 ExecuteRemoteFramesBroadcastMethod(
312 base::BindRepeating(
313 [](blink::mojom::InsecureRequestPolicy policy,
314 RenderFrameProxyHost* proxy) {
315 proxy->GetAssociatedRemoteFrame()->EnforceInsecureRequestPolicy(
316 policy);
317 },
318 policy),
Sharon Yang6b5313432023-03-24 05:07:57319 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolariae3521432021-12-14 11:27:43320 replication_state_->insecure_request_policy = policy;
321}
322
323void BrowsingContextState::SetInsecureNavigationsSet(
324 const std::vector<uint32_t>& insecure_navigations_set) {
325 DCHECK(std::is_sorted(insecure_navigations_set.begin(),
326 insecure_navigations_set.end()));
327 if (insecure_navigations_set == replication_state_->insecure_navigations_set)
328 return;
Dave Tapuska82b54012022-07-15 23:26:10329 ExecuteRemoteFramesBroadcastMethod(
330 base::BindRepeating(
331 [](const std::vector<uint32_t>& insecure_navigations_set,
332 RenderFrameProxyHost* proxy) {
333 proxy->GetAssociatedRemoteFrame()->EnforceInsecureNavigationsSet(
334 insecure_navigations_set);
335 },
336 std::ref(insecure_navigations_set)),
Sharon Yang6b5313432023-03-24 05:07:57337 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolariae3521432021-12-14 11:27:43338 replication_state_->insecure_navigations_set = insecure_navigations_set;
339}
340
341void BrowsingContextState::OnSetHadStickyUserActivationBeforeNavigation(
342 bool value) {
Dave Tapuska82b54012022-07-15 23:26:10343 ExecuteRemoteFramesBroadcastMethod(
344 base::BindRepeating(
345 [](bool value, RenderFrameProxyHost* proxy) {
346 proxy->GetAssociatedRemoteFrame()
347 ->SetHadStickyUserActivationBeforeNavigation(value);
348 },
349 value),
Sharon Yang6b5313432023-03-24 05:07:57350 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolariae3521432021-12-14 11:27:43351 replication_state_->has_received_user_gesture_before_nav = value;
352}
353
David Bokanfa230cc2022-07-22 18:02:33354void BrowsingContextState::SetIsAdFrame(bool is_ad_frame) {
355 if (is_ad_frame == replication_state_->is_ad_frame)
Harkiran Bolariae3521432021-12-14 11:27:43356 return;
357
David Bokanfa230cc2022-07-22 18:02:33358 replication_state_->is_ad_frame = is_ad_frame;
Dave Tapuska82b54012022-07-15 23:26:10359 ExecuteRemoteFramesBroadcastMethod(
360 base::BindRepeating(
David Bokanfa230cc2022-07-22 18:02:33361 [](bool is_ad_frame, RenderFrameProxyHost* proxy) {
362 proxy->GetAssociatedRemoteFrame()->SetReplicatedIsAdFrame(
363 is_ad_frame);
Dave Tapuska82b54012022-07-15 23:26:10364 },
David Bokanfa230cc2022-07-22 18:02:33365 is_ad_frame),
Sharon Yang6b5313432023-03-24 05:07:57366 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolariae3521432021-12-14 11:27:43367}
368
Harkiran Bolariae182a5942021-12-20 17:23:31369void BrowsingContextState::ActiveFrameCountIsZero(
Sharon Yanga2fe85e2022-02-09 21:38:29370 SiteInstanceGroup* site_instance_group) {
Sharon Yang417a5df2024-04-23 17:57:15371 CheckIfSiteInstanceGroupIsUnused(site_instance_group, kActiveFrameCount);
372}
373
374void BrowsingContextState::KeepAliveCountIsZero(
375 SiteInstanceGroup* site_instance_group) {
376 CheckIfSiteInstanceGroupIsUnused(site_instance_group, kKeepAliveCount);
377}
378
379void BrowsingContextState::CheckIfSiteInstanceGroupIsUnused(
380 SiteInstanceGroup* site_instance_group,
381 RefCountType ref_count_type) {
382 // Only delete the proxy if both counts are zero.
383 if (site_instance_group->keep_alive_count() > 0 ||
384 site_instance_group->active_frame_count() > 0) {
385 return;
386 }
387
388 // |site_instance_group| no longer contains any active RenderFrameHosts or
389 // NavigationStateKeepAlive objects, so we don't need to maintain a proxy
390 // there anymore.
Sharon Yanga2fe85e2022-02-09 21:38:29391 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31392 CHECK(proxy);
393
Sharon Yang417a5df2024-04-23 17:57:15394 if (kActiveFrameCount) {
395 TRACE_EVENT_INSTANT("navigation",
396 "BrowsingContextState::ActiveFrameCountIsZero",
397 ChromeTrackEvent::kBrowsingContextState, this,
398 ChromeTrackEvent::kRenderFrameProxyHost, proxy);
399 } else if (kKeepAliveCount) {
400 TRACE_EVENT_INSTANT("navigation",
401 "BrowsingContextState::KeepAliveCountIsZero",
402 ChromeTrackEvent::kBrowsingContextState, this,
403 ChromeTrackEvent::kRenderFrameProxyHost, proxy);
404 }
Harkiran Bolariaa8347782022-04-06 09:25:11405
Sharon Yanga2fe85e2022-02-09 21:38:29406 DeleteRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31407}
408
409void BrowsingContextState::RenderProcessGone(
Sharon Yanga2fe85e2022-02-09 21:38:29410 SiteInstanceGroup* site_instance_group,
Harkiran Bolariae182a5942021-12-20 17:23:31411 const ChildProcessTerminationInfo& info) {
Harkiran Bolariae45272d2022-04-12 08:05:01412 GetRenderFrameProxyHost(site_instance_group,
413 ProxyAccessMode::kAllowOuterDelegate)
Sharon Yanga2fe85e2022-02-09 21:38:29414 ->SetRenderFrameProxyCreated(false);
Harkiran Bolariae182a5942021-12-20 17:23:31415}
416
Harkiran Bolaria5ce27632022-01-20 15:05:05417void BrowsingContextState::SendFramePolicyUpdatesToProxies(
Sharon Yang571baee2022-03-18 19:01:54418 SiteInstanceGroup* parent_group,
Harkiran Bolaria5ce27632022-01-20 15:05:05419 const blink::FramePolicy& frame_policy) {
420 // Notify all of the frame's proxies about updated policies, excluding
421 // the parent process since it already knows the latest state.
Dave Tapuska82b54012022-07-15 23:26:10422 ExecuteRemoteFramesBroadcastMethod(
423 base::BindRepeating(
424 [](SiteInstanceGroup* parent_group,
425 const blink::FramePolicy& frame_policy,
426 RenderFrameProxyHost* proxy) {
427 if (proxy->site_instance_group() == parent_group)
428 return;
429 proxy->GetAssociatedRemoteFrame()->DidUpdateFramePolicy(
430 frame_policy);
431 },
432 base::Unretained(parent_group), std::ref(frame_policy)),
Sharon Yang6b5313432023-03-24 05:07:57433 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria5ce27632022-01-20 15:05:05434}
435
Harkiran Bolaria3f83fba72022-03-10 17:48:40436void BrowsingContextState::OnDidStartLoading() {
Dave Tapuska82b54012022-07-15 23:26:10437 ExecuteRemoteFramesBroadcastMethod(
438 base::BindRepeating([](RenderFrameProxyHost* proxy) {
439 proxy->GetAssociatedRemoteFrame()->DidStartLoading();
440 }),
Sharon Yang6b5313432023-03-24 05:07:57441 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40442}
443
444void BrowsingContextState::OnDidStopLoading() {
Dave Tapuska82b54012022-07-15 23:26:10445 ExecuteRemoteFramesBroadcastMethod(
446 base::BindRepeating([](RenderFrameProxyHost* proxy) {
447 proxy->GetAssociatedRemoteFrame()->DidStopLoading();
448 }),
Sharon Yang6b5313432023-03-24 05:07:57449 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40450}
451
Harkiran Bolaria0b3bdef02022-03-10 13:04:40452void BrowsingContextState::ResetProxyHosts() {
453 for (const auto& pair : proxy_hosts_) {
454 pair.second->site_instance_group()->RemoveObserver(this);
455 }
456 proxy_hosts_.clear();
457}
458
Sharon Yang571baee2022-03-18 19:01:54459void BrowsingContextState::UpdateOpener(
460 SiteInstanceGroup* source_site_instance_group) {
Harkiran Bolaria3f83fba72022-03-10 17:48:40461 for (const auto& pair : proxy_hosts_) {
Sharon Yang571baee2022-03-18 19:01:54462 if (pair.second->site_instance_group() == source_site_instance_group)
Harkiran Bolaria3f83fba72022-03-10 17:48:40463 continue;
464 pair.second->UpdateOpener();
465 }
466}
467
468void BrowsingContextState::OnDidUpdateFrameOwnerProperties(
469 const blink::mojom::FrameOwnerProperties& properties) {
470 // Notify this frame's proxies if they live in a different process from its
471 // parent. This is only currently needed for the allowFullscreen property,
472 // since that can be queried on RemoteFrame ancestors.
473 //
474 // TODO(alexmos): It would be sufficient to only send this update to proxies
475 // in the current FrameTree.
Dave Tapuska82b54012022-07-15 23:26:10476 ExecuteRemoteFramesBroadcastMethod(
477 base::BindRepeating(
478 [](SiteInstanceGroup* parent_group,
479 const blink::mojom::FrameOwnerProperties& properties,
480 RenderFrameProxyHost* proxy) {
481 if (proxy->site_instance_group() == parent_group)
482 return;
483 proxy->GetAssociatedRemoteFrame()->SetFrameOwnerProperties(
484 properties.Clone());
485 },
486 base::Unretained(parent_->GetSiteInstance()->group()),
487 std::ref(properties)),
Sharon Yang6b5313432023-03-24 05:07:57488 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40489}
490
491void BrowsingContextState::ExecuteRemoteFramesBroadcastMethod(
492 base::RepeatingCallback<void(RenderFrameProxyHost*)> callback,
Sharon Yang6b5313432023-03-24 05:07:57493 SiteInstanceGroup* group_to_skip,
Harkiran Bolaria3f83fba72022-03-10 17:48:40494 RenderFrameProxyHost* outer_delegate_proxy) {
495 for (const auto& pair : proxy_hosts_) {
496 if (outer_delegate_proxy == pair.second.get())
497 continue;
Sharon Yang6b5313432023-03-24 05:07:57498 if (pair.second->site_instance_group() == group_to_skip) {
Harkiran Bolaria3f83fba72022-03-10 17:48:40499 continue;
Sharon Yang6b5313432023-03-24 05:07:57500 }
Harkiran Bolaria3f83fba72022-03-10 17:48:40501 if (!pair.second->is_render_frame_proxy_live())
502 continue;
503 callback.Run(pair.second.get());
504 }
505}
506
Harkiran Bolaria3bf5457f2022-03-10 20:04:37507void BrowsingContextState::WriteIntoTrace(
Alexander Timin074cd182022-03-23 18:11:22508 perfetto::TracedProto<TraceProto> proto) const {
Arthur Hemery08d82882023-04-27 12:33:14509 if (browsing_instance_id_.has_value()) {
Harkiran Bolaria3bf5457f2022-03-10 20:04:37510 proto->set_browsing_instance_id(browsing_instance_id_.value().value());
Arthur Hemery08d82882023-04-27 12:33:14511 }
512
Arthur Hemerya3e593f2023-05-11 17:15:57513 if (coop_related_group_token_.has_value()) {
514 proto->set_coop_related_group_token(
515 coop_related_group_token_.value().ToString());
Arthur Hemery08d82882023-04-27 12:33:14516 }
Alexander Timin074cd182022-03-23 18:11:22517
518 perfetto::TracedDictionary dict = std::move(proto).AddDebugAnnotations();
519 dict.Add("this", static_cast<const void*>(this));
Harkiran Bolaria3bf5457f2022-03-10 20:04:37520}
521
Harkiran Bolaria875d4f62022-05-17 16:18:23522base::SafeRef<BrowsingContextState> BrowsingContextState::GetSafeRef() {
523 return weak_factory_.GetSafeRef();
524}
525
Alexander Timin07cad0762022-03-15 00:33:17526} // namespace content