blob: c6aab49502a0f8e0fc98e268222e1bbba7609bed [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"
Sandor Major878f8352025-02-18 20:16:0213#include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h"
Harkiran Bolaria5ce27632022-01-20 15:05:0514#include "services/network/public/cpp/web_sandbox_flags.h"
15#include "services/network/public/mojom/web_sandbox_flags.mojom.h"
16
Harkiran Bolaria8dec6f92021-12-07 14:57:1217namespace features {
Daniel Cheng0abd9f32022-09-22 04:20:1118BASE_FEATURE(kNewBrowsingContextStateOnBrowsingContextGroupSwap,
19 "NewBrowsingContextStateOnBrowsingContextGroupSwap",
20 base::FEATURE_DISABLED_BY_DEFAULT);
Harkiran Bolaria8dec6f92021-12-07 14:57:1221
22BrowsingContextStateImplementationType GetBrowsingContextMode() {
23 if (base::FeatureList::IsEnabled(
24 kNewBrowsingContextStateOnBrowsingContextGroupSwap)) {
25 return BrowsingContextStateImplementationType::
26 kSwapForCrossBrowsingInstanceNavigations;
27 }
28
29 return BrowsingContextStateImplementationType::
30 kLegacyOneToOneWithFrameTreeNode;
31}
32} // namespace features
33
34namespace content {
35
Harkiran Bolariaa8347782022-04-06 09:25:1136using perfetto::protos::pbzero::ChromeTrackEvent;
37
Harkiran Bolaria4eacb3a2021-12-13 20:03:4738BrowsingContextState::BrowsingContextState(
Harkiran Bolaria880a7632022-02-28 16:02:5039 blink::mojom::FrameReplicationStatePtr replication_state,
Arthur Sonzogni91fd79b2023-04-19 15:37:1440 RenderFrameHostImpl* parent,
Camille Lamyc9351922025-05-01 02:57:4441 std::optional<BrowsingInstanceId> browsing_instance_id)
Harkiran Bolaria0b3bdef02022-03-10 13:04:4042 : replication_state_(std::move(replication_state)),
43 parent_(parent),
Camille Lamyc9351922025-05-01 02:57:4444 browsing_instance_id_(browsing_instance_id) {
Patrick Monette3250ac42025-05-09 21:55:0145 TRACE_EVENT_BEGIN("navigation.debug", "BrowsingContextState",
Harkiran Bolariaa8347782022-04-06 09:25:1146 perfetto::Track::FromPointer(this),
47 "browsing_context_state_when_created", this);
48}
Harkiran Bolaria8dec6f92021-12-07 14:57:1249
Harkiran Bolariaa8347782022-04-06 09:25:1150BrowsingContextState::~BrowsingContextState() {
Patrick Monette3250ac42025-05-09 21:55:0151 TRACE_EVENT_END("navigation.debug", perfetto::Track::FromPointer(this));
W. James MacLean0fbe7dc52023-08-22 20:20:4852 CHECK(proxy_hosts_.empty());
Harkiran Bolariaa8347782022-04-06 09:25:1153}
Harkiran Bolaria4eacb3a2021-12-13 20:03:4754
Harkiran Bolaria5ce27632022-01-20 15:05:0555RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:0156 SiteInstanceGroup* site_instance_group,
57 ProxyAccessMode proxy_access_mode) const {
Peilin Wang9791d802023-05-09 19:07:3158 TRACE_EVENT_BEGIN("navigation.debug",
Harkiran Bolariaa8347782022-04-06 09:25:1159 "BrowsingContextState::GetRenderFrameProxyHost",
60 ChromeTrackEvent::kBrowsingContextState, this,
61 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group);
Harkiran Bolariae45272d2022-04-12 08:05:0162 auto* proxy =
63 GetRenderFrameProxyHostImpl(site_instance_group, proxy_access_mode);
Peilin Wang9791d802023-05-09 19:07:3164 TRACE_EVENT_END("navigation.debug", ChromeTrackEvent::kRenderFrameProxyHost,
65 proxy);
Harkiran Bolariaa8347782022-04-06 09:25:1166 return proxy;
67}
68
69RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHostImpl(
Harkiran Bolariae45272d2022-04-12 08:05:0170 SiteInstanceGroup* site_instance_group,
71 ProxyAccessMode proxy_access_mode) const {
Harkiran Bolaria5c5a97392022-03-10 14:18:5072 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:0173 features::BrowsingContextStateImplementationType::
74 kSwapForCrossBrowsingInstanceNavigations &&
75 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:5076 // CHECK to verify that the proxy is being accessed from the correct
77 // BrowsingContextState. As both BrowsingContextState (in non-legacy mode)
78 // and RenderFrameProxyHost (via SiteInstance) are tied to a given
Camille Lamyc9351922025-05-01 02:57:4479 // BrowsingInstance, the browsing_instance_id of the BrowsingContextState
Arthur Hemery08d82882023-04-27 12:33:1480 // (in the non-legacy mode) and of the SiteInstanceGroup should match. If
81 // they do not, the code calling this method has likely chosen the wrong
82 // BrowsingContextState (e.g. one from the current RenderFrameHost rather
83 // than from speculative or vice versa) – as this can lead to various
84 // unpredictable bugs in proxy management logic, we want to crash the
85 // browser here when this condition fails.
Harkiran Bolaria5c5a97392022-03-10 14:18:5086 //
Arthur Hemery08d82882023-04-27 12:33:1487 // Note: Outer delegates are an exception, and when we're expecting to
88 // interact with one, we should pass in the proper `proxy_access_mode` to
89 // not end up in this condition.
Camille Lamyc9351922025-05-01 02:57:4490 CHECK_EQ(browsing_instance_id_.value(),
91 site_instance_group->browsing_instance_id());
Harkiran Bolaria5c5a97392022-03-10 14:18:5092 }
Harkiran Bolaria5ce27632022-01-20 15:05:0593 auto it = proxy_hosts_.find(site_instance_group->GetId());
Harkiran Bolariaa8347782022-04-06 09:25:1194 if (it != proxy_hosts_.end()) {
Harkiran Bolaria5ce27632022-01-20 15:05:0595 return it->second.get();
Harkiran Bolariaa8347782022-04-06 09:25:1196 }
Harkiran Bolaria5ce27632022-01-20 15:05:0597 return nullptr;
98}
99
Harkiran Bolaria5c5a97392022-03-10 14:18:50100void BrowsingContextState::DeleteRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:01101 SiteInstanceGroup* site_instance_group,
102 ProxyAccessMode proxy_access_mode) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50103 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:01104 features::BrowsingContextStateImplementationType::
105 kSwapForCrossBrowsingInstanceNavigations &&
106 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50107 // See comments in GetRenderFrameProxyHost for why this check is needed.
Camille Lamyc9351922025-05-01 02:57:44108 CHECK_EQ(browsing_instance_id_.value(),
109 site_instance_group->browsing_instance_id());
Harkiran Bolaria5c5a97392022-03-10 14:18:50110 }
Harkiran Bolariaa8347782022-04-06 09:25:11111 TRACE_EVENT("navigation", "BrowsingContextState::DeleteRenderFrameProxyHost",
112 ChromeTrackEvent::kBrowsingContextState, this,
113 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group);
Harkiran Bolaria5c5a97392022-03-10 14:18:50114 site_instance_group->RemoveObserver(this);
115 proxy_hosts_.erase(site_instance_group->GetId());
116}
117
118RenderFrameProxyHost* BrowsingContextState::CreateRenderFrameProxyHost(
Sharon Yangdcc5f252024-05-09 18:27:23119 SiteInstanceGroup* site_instance_group,
Harkiran Bolaria5c5a97392022-03-10 14:18:50120 const scoped_refptr<RenderViewHostImpl>& rvh,
Harkiran Bolariae45272d2022-04-12 08:05:01121 FrameTreeNode* frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27122 ProxyAccessMode proxy_access_mode,
123 const blink::RemoteFrameToken& frame_token) {
Harkiran Bolariaa8347782022-04-06 09:25:11124 TRACE_EVENT_BEGIN(
125 "navigation", "BrowsingContextState::CreateRenderFrameProxyHost",
126 ChromeTrackEvent::kBrowsingContextState, this,
Sharon Yangdcc5f252024-05-09 18:27:23127 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group,
Harkiran Bolariaa8347782022-04-06 09:25:11128 ChromeTrackEvent::kRenderViewHost, rvh ? rvh.get() : nullptr,
129 ChromeTrackEvent::kFrameTreeNodeInfo, frame_tree_node);
130
Harkiran Bolaria5c5a97392022-03-10 14:18:50131 if (features::GetBrowsingContextMode() ==
132 features::BrowsingContextStateImplementationType::
133 kLegacyOneToOneWithFrameTreeNode) {
134 DCHECK_EQ(this,
135 frame_tree_node->current_frame_host()->browsing_context_state());
136 }
137
138 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:01139 features::BrowsingContextStateImplementationType::
140 kSwapForCrossBrowsingInstanceNavigations &&
141 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50142 // See comments in GetRenderFrameProxyHost for why this check is needed.
Camille Lamyc9351922025-05-01 02:57:44143 CHECK_EQ(browsing_instance_id_.value(),
144 site_instance_group->browsing_instance_id());
Harkiran Bolaria5c5a97392022-03-10 14:18:50145 }
146
Sharon Yangdcc5f252024-05-09 18:27:23147 auto site_instance_group_id = site_instance_group->GetId();
Harkiran Bolaria5c5a97392022-03-10 14:18:50148 CHECK(proxy_hosts_.find(site_instance_group_id) == proxy_hosts_.end())
149 << "A proxy already existed for this SiteInstanceGroup.";
Dave Tapuska144570102022-08-02 19:28:27150 RenderFrameProxyHost* proxy_host = new RenderFrameProxyHost(
Sharon Yangdcc5f252024-05-09 18:27:23151 site_instance_group, std::move(rvh), frame_tree_node, frame_token);
Harkiran Bolaria5c5a97392022-03-10 14:18:50152 proxy_hosts_[site_instance_group_id] = base::WrapUnique(proxy_host);
Sharon Yangdcc5f252024-05-09 18:27:23153 site_instance_group->AddObserver(this);
Harkiran Bolaria5c5a97392022-03-10 14:18:50154
Harkiran Bolariaa8347782022-04-06 09:25:11155 TRACE_EVENT_END("navigation", ChromeTrackEvent::kRenderFrameProxyHost,
156 proxy_host);
Harkiran Bolaria5c5a97392022-03-10 14:18:50157 return proxy_host;
158}
159
Harkiran Bolariae45272d2022-04-12 08:05:01160RenderFrameProxyHost* BrowsingContextState::CreateOuterDelegateProxy(
Sharon Yangdcc5f252024-05-09 18:27:23161 SiteInstanceGroup* outer_contents_site_instance_group,
Dave Tapuska144570102022-08-02 19:28:27162 FrameTreeNode* frame_tree_node,
163 const blink::RemoteFrameToken& frame_token) {
Harkiran Bolariae45272d2022-04-12 08:05:01164 // We only get here when Delegate for this manager is an inner delegate.
Sharon Yangdcc5f252024-05-09 18:27:23165 return CreateRenderFrameProxyHost(outer_contents_site_instance_group,
Harkiran Bolariae45272d2022-04-12 08:05:01166 /*rvh=*/nullptr, frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27167 ProxyAccessMode::kAllowOuterDelegate,
168 frame_token);
Harkiran Bolariae45272d2022-04-12 08:05:01169}
170
Harkiran Bolariad22a1dca2022-02-22 17:01:12171size_t BrowsingContextState::GetProxyCount() {
172 return proxy_hosts_.size();
173}
174
Harkiran Bolaria5ce27632022-01-20 15:05:05175bool BrowsingContextState::UpdateFramePolicyHeaders(
176 network::mojom::WebSandboxFlags sandbox_flags,
Sandor Major878f8352025-02-18 20:16:02177 const network::ParsedPermissionsPolicy& parsed_header) {
Harkiran Bolaria5ce27632022-01-20 15:05:05178 bool changed = false;
179 if (replication_state_->permissions_policy_header != parsed_header) {
180 replication_state_->permissions_policy_header = parsed_header;
181 changed = true;
182 }
183 // TODO(iclelland): Kill the renderer if sandbox flags is not a subset of the
184 // currently effective sandbox flags from the frame. https://crbug.com/740556
185 network::mojom::WebSandboxFlags updated_flags =
186 sandbox_flags | replication_state_->frame_policy.sandbox_flags;
187 if (replication_state_->active_sandbox_flags != updated_flags) {
188 replication_state_->active_sandbox_flags = updated_flags;
189 changed = true;
190 }
191 // Notify any proxies if the policies have been changed.
192 if (changed) {
Charlie Reis0650ad0d2024-12-06 18:12:35193 TRACE_EVENT("navigation",
194 "BrowsingContextState::UpdateFramePolicyHeaders broadcast");
Dave Tapuska82b54012022-07-15 23:26:10195 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31196 [this](RenderFrameProxyHost* proxy) {
197 proxy->GetAssociatedRemoteFrame()->DidSetFramePolicyHeaders(
198 replication_state_->active_sandbox_flags,
199 replication_state_->permissions_policy_header);
200 },
Sharon Yang6b5313432023-03-24 05:07:57201 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria5ce27632022-01-20 15:05:05202 }
203 return changed;
204}
205
206bool BrowsingContextState::CommitFramePolicy(
207 const blink::FramePolicy& new_frame_policy) {
208 // Documents create iframes, iframes host new documents. Both are associated
209 // with sandbox flags. They are required to be stricter or equal to their
210 // owner when they change, as we go down.
Alison Gale81f4f2c72024-04-22 19:33:31211 // TODO(crbug.com/40202483). Enforce the invariant mentioned above,
Harkiran Bolaria5ce27632022-01-20 15:05:05212 // once the interactions with fenced frame has been tested and clarified.
213
214 bool did_change_flags = new_frame_policy.sandbox_flags !=
215 replication_state_->frame_policy.sandbox_flags;
216 bool did_change_container_policy =
217 new_frame_policy.container_policy !=
218 replication_state_->frame_policy.container_policy;
219 bool did_change_required_document_policy =
220 new_frame_policy.required_document_policy !=
221 replication_state_->frame_policy.required_document_policy;
Harkiran Bolaria5ce27632022-01-20 15:05:05222
Harkiran Bolaria4eacb3a2021-12-13 20:03:47223 if (did_change_flags) {
224 replication_state_->frame_policy.sandbox_flags =
225 new_frame_policy.sandbox_flags;
226 }
227 if (did_change_container_policy) {
228 replication_state_->frame_policy.container_policy =
229 new_frame_policy.container_policy;
230 }
231 if (did_change_required_document_policy) {
232 replication_state_->frame_policy.required_document_policy =
233 new_frame_policy.required_document_policy;
234 }
Harkiran Bolariae3521432021-12-14 11:27:43235
Harkiran Bolaria5ce27632022-01-20 15:05:05236 UpdateFramePolicyHeaders(new_frame_policy.sandbox_flags,
237 replication_state_->permissions_policy_header);
238 return did_change_flags || did_change_container_policy ||
239 did_change_required_document_policy;
Harkiran Bolaria7fdb4c642021-12-20 12:47:00240}
241
Harkiran Bolaria880a7632022-02-28 16:02:50242void BrowsingContextState::SetFrameName(const std::string& name,
243 const std::string& unique_name) {
244 if (name == replication_state_->name) {
245 // |unique_name| shouldn't change unless |name| changes.
246 DCHECK_EQ(unique_name, replication_state_->unique_name);
247 return;
248 }
249
250 if (parent_) {
251 // Non-main frames should have a non-empty unique name.
252 DCHECK(!unique_name.empty());
253 } else {
254 // Unique name of main frames should always stay empty.
255 DCHECK(unique_name.empty());
256 }
257
258 // Note the unique name should only be able to change before the first real
259 // load is committed, but that's not strongly enforced here.
Charlie Reis0650ad0d2024-12-06 18:12:35260 {
261 TRACE_EVENT("navigation", "BrowsingContextState::SetFrameName broadcast",
262 "name", name, "unique_name", unique_name);
263 ExecuteRemoteFramesBroadcastMethod(
264 [&name, &unique_name](RenderFrameProxyHost* proxy) {
265 proxy->GetAssociatedRemoteFrame()->SetReplicatedName(name,
266 unique_name);
267 },
268 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
269 }
Harkiran Bolaria880a7632022-02-28 16:02:50270 replication_state_->unique_name = unique_name;
271 replication_state_->name = name;
272}
273
Harkiran Bolariae3521432021-12-14 11:27:43274void BrowsingContextState::SetCurrentOrigin(
275 const url::Origin& origin,
276 bool is_potentially_trustworthy_unique_origin) {
277 if (origin.IsSameOriginWith(replication_state_->origin) &&
278 replication_state_->has_potentially_trustworthy_unique_origin ==
279 is_potentially_trustworthy_unique_origin) {
280 return;
281 }
282
Charlie Reis0650ad0d2024-12-06 18:12:35283 {
284 TRACE_EVENT("navigation",
285 "BrowsingContextState::SetCurrentOrigin broadcast", "origin",
286 origin);
287 ExecuteRemoteFramesBroadcastMethod(
288 [&origin, is_potentially_trustworthy_unique_origin](
289 RenderFrameProxyHost* proxy) {
290 proxy->GetAssociatedRemoteFrame()->SetReplicatedOrigin(
291 origin, is_potentially_trustworthy_unique_origin);
292 },
293 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
294 }
Harkiran Bolariae3521432021-12-14 11:27:43295
296 replication_state_->origin = origin;
297 replication_state_->has_potentially_trustworthy_unique_origin =
298 is_potentially_trustworthy_unique_origin;
299}
300
301void BrowsingContextState::SetInsecureRequestPolicy(
302 blink::mojom::InsecureRequestPolicy policy) {
303 if (policy == replication_state_->insecure_request_policy)
304 return;
Charlie Reis0650ad0d2024-12-06 18:12:35305 {
306 TRACE_EVENT("navigation",
307 "BrowsingContextState::SetInsecureRequestPolicy broadcast");
308 ExecuteRemoteFramesBroadcastMethod(
309 [policy](RenderFrameProxyHost* proxy) {
310 proxy->GetAssociatedRemoteFrame()->EnforceInsecureRequestPolicy(
311 policy);
312 },
313 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
314 }
Harkiran Bolariae3521432021-12-14 11:27:43315 replication_state_->insecure_request_policy = policy;
316}
317
318void BrowsingContextState::SetInsecureNavigationsSet(
319 const std::vector<uint32_t>& insecure_navigations_set) {
320 DCHECK(std::is_sorted(insecure_navigations_set.begin(),
321 insecure_navigations_set.end()));
322 if (insecure_navigations_set == replication_state_->insecure_navigations_set)
323 return;
Charlie Reis0650ad0d2024-12-06 18:12:35324 {
325 TRACE_EVENT("navigation",
326 "BrowsingContextState::SetInsecureNavigationsSet broadcast");
327 ExecuteRemoteFramesBroadcastMethod(
328 [&insecure_navigations_set](RenderFrameProxyHost* proxy) {
329 proxy->GetAssociatedRemoteFrame()->EnforceInsecureNavigationsSet(
330 insecure_navigations_set);
331 },
332 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
333 }
Harkiran Bolariae3521432021-12-14 11:27:43334 replication_state_->insecure_navigations_set = insecure_navigations_set;
335}
336
337void BrowsingContextState::OnSetHadStickyUserActivationBeforeNavigation(
338 bool value) {
Charlie Reis0650ad0d2024-12-06 18:12:35339 {
340 TRACE_EVENT("navigation",
341 "BrowsingContextState::"
342 "OnSetHadStickyUserActivationBeforeNavigation broadcast",
343 "value", value);
344 ExecuteRemoteFramesBroadcastMethod(
345 [value](RenderFrameProxyHost* proxy) {
346 proxy->GetAssociatedRemoteFrame()
347 ->SetHadStickyUserActivationBeforeNavigation(value);
348 },
349 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
350 }
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;
Charlie Reis0650ad0d2024-12-06 18:12:35359 {
360 TRACE_EVENT("navigation", "BrowsingContextState::SetIsAdFrame broadcast",
361 "is_ad_frame", is_ad_frame);
362 ExecuteRemoteFramesBroadcastMethod(
363 [is_ad_frame](RenderFrameProxyHost* proxy) {
364 proxy->GetAssociatedRemoteFrame()->SetReplicatedIsAdFrame(
365 is_ad_frame);
366 },
367 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
368 }
Harkiran Bolariae3521432021-12-14 11:27:43369}
370
Harkiran Bolariae182a5942021-12-20 17:23:31371void BrowsingContextState::ActiveFrameCountIsZero(
Sharon Yanga2fe85e2022-02-09 21:38:29372 SiteInstanceGroup* site_instance_group) {
Sharon Yang417a5df2024-04-23 17:57:15373 CheckIfSiteInstanceGroupIsUnused(site_instance_group, kActiveFrameCount);
374}
375
376void BrowsingContextState::KeepAliveCountIsZero(
377 SiteInstanceGroup* site_instance_group) {
378 CheckIfSiteInstanceGroupIsUnused(site_instance_group, kKeepAliveCount);
379}
380
381void BrowsingContextState::CheckIfSiteInstanceGroupIsUnused(
382 SiteInstanceGroup* site_instance_group,
383 RefCountType ref_count_type) {
384 // Only delete the proxy if both counts are zero.
385 if (site_instance_group->keep_alive_count() > 0 ||
386 site_instance_group->active_frame_count() > 0) {
387 return;
388 }
389
390 // |site_instance_group| no longer contains any active RenderFrameHosts or
391 // NavigationStateKeepAlive objects, so we don't need to maintain a proxy
392 // there anymore.
Sharon Yanga2fe85e2022-02-09 21:38:29393 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31394 CHECK(proxy);
395
Sharon Yang417a5df2024-04-23 17:57:15396 if (kActiveFrameCount) {
397 TRACE_EVENT_INSTANT("navigation",
398 "BrowsingContextState::ActiveFrameCountIsZero",
399 ChromeTrackEvent::kBrowsingContextState, this,
400 ChromeTrackEvent::kRenderFrameProxyHost, proxy);
401 } else if (kKeepAliveCount) {
402 TRACE_EVENT_INSTANT("navigation",
403 "BrowsingContextState::KeepAliveCountIsZero",
404 ChromeTrackEvent::kBrowsingContextState, this,
405 ChromeTrackEvent::kRenderFrameProxyHost, proxy);
406 }
Harkiran Bolariaa8347782022-04-06 09:25:11407
Sharon Yanga2fe85e2022-02-09 21:38:29408 DeleteRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31409}
410
411void BrowsingContextState::RenderProcessGone(
Sharon Yanga2fe85e2022-02-09 21:38:29412 SiteInstanceGroup* site_instance_group,
Harkiran Bolariae182a5942021-12-20 17:23:31413 const ChildProcessTerminationInfo& info) {
Harkiran Bolariae45272d2022-04-12 08:05:01414 GetRenderFrameProxyHost(site_instance_group,
415 ProxyAccessMode::kAllowOuterDelegate)
Sharon Yanga2fe85e2022-02-09 21:38:29416 ->SetRenderFrameProxyCreated(false);
Harkiran Bolariae182a5942021-12-20 17:23:31417}
418
Harkiran Bolaria5ce27632022-01-20 15:05:05419void BrowsingContextState::SendFramePolicyUpdatesToProxies(
Sharon Yang571baee2022-03-18 19:01:54420 SiteInstanceGroup* parent_group,
Harkiran Bolaria5ce27632022-01-20 15:05:05421 const blink::FramePolicy& frame_policy) {
422 // Notify all of the frame's proxies about updated policies, excluding
423 // the parent process since it already knows the latest state.
Charlie Reis0650ad0d2024-12-06 18:12:35424 TRACE_EVENT(
425 "navigation",
426 "BrowsingContextState::SendFramePolicyUpdatesToProxies broadcast");
Dave Tapuska82b54012022-07-15 23:26:10427 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31428 [parent_group, &frame_policy](RenderFrameProxyHost* proxy) {
429 if (proxy->site_instance_group() == parent_group) {
430 return;
431 }
432 proxy->GetAssociatedRemoteFrame()->DidUpdateFramePolicy(frame_policy);
433 },
Sharon Yang6b5313432023-03-24 05:07:57434 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria5ce27632022-01-20 15:05:05435}
436
Harkiran Bolaria3f83fba72022-03-10 17:48:40437void BrowsingContextState::OnDidStartLoading() {
Charlie Reis0650ad0d2024-12-06 18:12:35438 TRACE_EVENT("navigation",
439 "BrowsingContextState::OnDidStartLoading broadcast");
Dave Tapuska82b54012022-07-15 23:26:10440 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31441 [](RenderFrameProxyHost* proxy) {
Dave Tapuska82b54012022-07-15 23:26:10442 proxy->GetAssociatedRemoteFrame()->DidStartLoading();
Kevin McNee7705fe82024-11-07 18:56:31443 },
Sharon Yang6b5313432023-03-24 05:07:57444 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40445}
446
447void BrowsingContextState::OnDidStopLoading() {
Charlie Reis0650ad0d2024-12-06 18:12:35448 TRACE_EVENT("navigation", "BrowsingContextState::OnDidStopLoading broadcast");
Dave Tapuska82b54012022-07-15 23:26:10449 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31450 [](RenderFrameProxyHost* proxy) {
Dave Tapuska82b54012022-07-15 23:26:10451 proxy->GetAssociatedRemoteFrame()->DidStopLoading();
Kevin McNee7705fe82024-11-07 18:56:31452 },
Sharon Yang6b5313432023-03-24 05:07:57453 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40454}
455
Harkiran Bolaria0b3bdef02022-03-10 13:04:40456void BrowsingContextState::ResetProxyHosts() {
457 for (const auto& pair : proxy_hosts_) {
458 pair.second->site_instance_group()->RemoveObserver(this);
459 }
460 proxy_hosts_.clear();
461}
462
Sharon Yang571baee2022-03-18 19:01:54463void BrowsingContextState::UpdateOpener(
464 SiteInstanceGroup* source_site_instance_group) {
Harkiran Bolaria3f83fba72022-03-10 17:48:40465 for (const auto& pair : proxy_hosts_) {
Sharon Yang571baee2022-03-18 19:01:54466 if (pair.second->site_instance_group() == source_site_instance_group)
Harkiran Bolaria3f83fba72022-03-10 17:48:40467 continue;
468 pair.second->UpdateOpener();
469 }
470}
471
472void BrowsingContextState::OnDidUpdateFrameOwnerProperties(
473 const blink::mojom::FrameOwnerProperties& properties) {
474 // Notify this frame's proxies if they live in a different process from its
475 // parent. This is only currently needed for the allowFullscreen property,
476 // since that can be queried on RemoteFrame ancestors.
477 //
478 // TODO(alexmos): It would be sufficient to only send this update to proxies
479 // in the current FrameTree.
Kevin McNee7705fe82024-11-07 18:56:31480 SiteInstanceGroup* parent_group = parent_->GetSiteInstance()->group();
Charlie Reis0650ad0d2024-12-06 18:12:35481 {
482 TRACE_EVENT(
483 "navigation",
484 "BrowsingContextState::OnDidUpdateFrameOwnerProperties broadcast");
485 ExecuteRemoteFramesBroadcastMethod(
486 [parent_group, &properties](RenderFrameProxyHost* proxy) {
487 if (proxy->site_instance_group() == parent_group) {
488 return;
489 }
490 proxy->GetAssociatedRemoteFrame()->SetFrameOwnerProperties(
491 properties.Clone());
492 },
493 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
494 }
Harkiran Bolaria3f83fba72022-03-10 17:48:40495}
496
497void BrowsingContextState::ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31498 base::FunctionRef<void(RenderFrameProxyHost*)> callback,
Sharon Yang6b5313432023-03-24 05:07:57499 SiteInstanceGroup* group_to_skip,
Harkiran Bolaria3f83fba72022-03-10 17:48:40500 RenderFrameProxyHost* outer_delegate_proxy) {
Charlie Reis0650ad0d2024-12-06 18:12:35501 TRACE_EVENT("navigation",
502 "BrowsingContextState::ExecuteRemoteFramesBroadcastMethod");
Harkiran Bolaria3f83fba72022-03-10 17:48:40503 for (const auto& pair : proxy_hosts_) {
504 if (outer_delegate_proxy == pair.second.get())
505 continue;
Sharon Yang6b5313432023-03-24 05:07:57506 if (pair.second->site_instance_group() == group_to_skip) {
Harkiran Bolaria3f83fba72022-03-10 17:48:40507 continue;
Sharon Yang6b5313432023-03-24 05:07:57508 }
Harkiran Bolaria3f83fba72022-03-10 17:48:40509 if (!pair.second->is_render_frame_proxy_live())
510 continue;
Kevin McNee7705fe82024-11-07 18:56:31511 callback(pair.second.get());
Harkiran Bolaria3f83fba72022-03-10 17:48:40512 }
513}
514
Harkiran Bolaria3bf5457f2022-03-10 20:04:37515void BrowsingContextState::WriteIntoTrace(
Alexander Timin074cd182022-03-23 18:11:22516 perfetto::TracedProto<TraceProto> proto) const {
Arthur Hemery08d82882023-04-27 12:33:14517 if (browsing_instance_id_.has_value()) {
Harkiran Bolaria3bf5457f2022-03-10 20:04:37518 proto->set_browsing_instance_id(browsing_instance_id_.value().value());
Arthur Hemery08d82882023-04-27 12:33:14519 }
520
Alexander Timin074cd182022-03-23 18:11:22521 perfetto::TracedDictionary dict = std::move(proto).AddDebugAnnotations();
522 dict.Add("this", static_cast<const void*>(this));
Harkiran Bolaria3bf5457f2022-03-10 20:04:37523}
524
Harkiran Bolaria875d4f62022-05-17 16:18:23525base::SafeRef<BrowsingContextState> BrowsingContextState::GetSafeRef() {
526 return weak_factory_.GetSafeRef();
527}
528
Alexander Timin07cad0762022-03-15 00:33:17529} // namespace content