blob: f6a8c865cdd8df97824b1538652601ed00230b2c [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 {
Xiaohan Wang2b2aabb2025-08-19 23:42:3018BASE_FEATURE(NewBrowsingContextStateOnBrowsingContextGroupSwap,
Daniel Cheng0abd9f32022-09-22 04:20:1119 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,
Camille Lamyc9351922025-05-01 02:57:4440 std::optional<BrowsingInstanceId> browsing_instance_id)
Harkiran Bolaria0b3bdef02022-03-10 13:04:4041 : replication_state_(std::move(replication_state)),
42 parent_(parent),
Camille Lamyc9351922025-05-01 02:57:4443 browsing_instance_id_(browsing_instance_id) {
Patrick Monette3250ac42025-05-09 21:55:0144 TRACE_EVENT_BEGIN("navigation.debug", "BrowsingContextState",
Harkiran Bolariaa8347782022-04-06 09:25:1145 perfetto::Track::FromPointer(this),
46 "browsing_context_state_when_created", this);
47}
Harkiran Bolaria8dec6f92021-12-07 14:57:1248
Harkiran Bolariaa8347782022-04-06 09:25:1149BrowsingContextState::~BrowsingContextState() {
Patrick Monette3250ac42025-05-09 21:55:0150 TRACE_EVENT_END("navigation.debug", perfetto::Track::FromPointer(this));
W. James MacLean0fbe7dc52023-08-22 20:20:4851 CHECK(proxy_hosts_.empty());
Harkiran Bolariaa8347782022-04-06 09:25:1152}
Harkiran Bolaria4eacb3a2021-12-13 20:03:4753
Harkiran Bolaria5ce27632022-01-20 15:05:0554RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:0155 SiteInstanceGroup* site_instance_group,
56 ProxyAccessMode proxy_access_mode) const {
Peilin Wang9791d802023-05-09 19:07:3157 TRACE_EVENT_BEGIN("navigation.debug",
Harkiran Bolariaa8347782022-04-06 09:25:1158 "BrowsingContextState::GetRenderFrameProxyHost",
59 ChromeTrackEvent::kBrowsingContextState, this,
60 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group);
Harkiran Bolariae45272d2022-04-12 08:05:0161 auto* proxy =
62 GetRenderFrameProxyHostImpl(site_instance_group, proxy_access_mode);
Peilin Wang9791d802023-05-09 19:07:3163 TRACE_EVENT_END("navigation.debug", ChromeTrackEvent::kRenderFrameProxyHost,
64 proxy);
Harkiran Bolariaa8347782022-04-06 09:25:1165 return proxy;
66}
67
68RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHostImpl(
Harkiran Bolariae45272d2022-04-12 08:05:0169 SiteInstanceGroup* site_instance_group,
70 ProxyAccessMode proxy_access_mode) const {
Harkiran Bolaria5c5a97392022-03-10 14:18:5071 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:0172 features::BrowsingContextStateImplementationType::
73 kSwapForCrossBrowsingInstanceNavigations &&
74 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:5075 // CHECK to verify that the proxy is being accessed from the correct
76 // BrowsingContextState. As both BrowsingContextState (in non-legacy mode)
77 // and RenderFrameProxyHost (via SiteInstance) are tied to a given
Camille Lamyc9351922025-05-01 02:57:4478 // BrowsingInstance, the browsing_instance_id of the BrowsingContextState
Arthur Hemery08d82882023-04-27 12:33:1479 // (in the non-legacy mode) and of the SiteInstanceGroup should match. If
80 // they do not, the code calling this method has likely chosen the wrong
81 // BrowsingContextState (e.g. one from the current RenderFrameHost rather
82 // than from speculative or vice versa) – as this can lead to various
83 // unpredictable bugs in proxy management logic, we want to crash the
84 // browser here when this condition fails.
Harkiran Bolaria5c5a97392022-03-10 14:18:5085 //
Arthur Hemery08d82882023-04-27 12:33:1486 // Note: Outer delegates are an exception, and when we're expecting to
87 // interact with one, we should pass in the proper `proxy_access_mode` to
88 // not end up in this condition.
Camille Lamyc9351922025-05-01 02:57:4489 CHECK_EQ(browsing_instance_id_.value(),
90 site_instance_group->browsing_instance_id());
Harkiran Bolaria5c5a97392022-03-10 14:18:5091 }
Harkiran Bolaria5ce27632022-01-20 15:05:0592 auto it = proxy_hosts_.find(site_instance_group->GetId());
Harkiran Bolariaa8347782022-04-06 09:25:1193 if (it != proxy_hosts_.end()) {
Harkiran Bolaria5ce27632022-01-20 15:05:0594 return it->second.get();
Harkiran Bolariaa8347782022-04-06 09:25:1195 }
Harkiran Bolaria5ce27632022-01-20 15:05:0596 return nullptr;
97}
98
Harkiran Bolaria5c5a97392022-03-10 14:18:5099void BrowsingContextState::DeleteRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:01100 SiteInstanceGroup* site_instance_group,
101 ProxyAccessMode proxy_access_mode) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50102 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:01103 features::BrowsingContextStateImplementationType::
104 kSwapForCrossBrowsingInstanceNavigations &&
105 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50106 // See comments in GetRenderFrameProxyHost for why this check is needed.
Camille Lamyc9351922025-05-01 02:57:44107 CHECK_EQ(browsing_instance_id_.value(),
108 site_instance_group->browsing_instance_id());
Harkiran Bolaria5c5a97392022-03-10 14:18:50109 }
Harkiran Bolariaa8347782022-04-06 09:25:11110 TRACE_EVENT("navigation", "BrowsingContextState::DeleteRenderFrameProxyHost",
111 ChromeTrackEvent::kBrowsingContextState, this,
112 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group);
Harkiran Bolaria5c5a97392022-03-10 14:18:50113 site_instance_group->RemoveObserver(this);
114 proxy_hosts_.erase(site_instance_group->GetId());
115}
116
117RenderFrameProxyHost* BrowsingContextState::CreateRenderFrameProxyHost(
Sharon Yangdcc5f252024-05-09 18:27:23118 SiteInstanceGroup* site_instance_group,
Harkiran Bolaria5c5a97392022-03-10 14:18:50119 const scoped_refptr<RenderViewHostImpl>& rvh,
Harkiran Bolariae45272d2022-04-12 08:05:01120 FrameTreeNode* frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27121 ProxyAccessMode proxy_access_mode,
122 const blink::RemoteFrameToken& frame_token) {
Harkiran Bolariaa8347782022-04-06 09:25:11123 TRACE_EVENT_BEGIN(
124 "navigation", "BrowsingContextState::CreateRenderFrameProxyHost",
125 ChromeTrackEvent::kBrowsingContextState, this,
Sharon Yangdcc5f252024-05-09 18:27:23126 ChromeTrackEvent::kSiteInstanceGroup, site_instance_group,
Harkiran Bolariaa8347782022-04-06 09:25:11127 ChromeTrackEvent::kRenderViewHost, rvh ? rvh.get() : nullptr,
128 ChromeTrackEvent::kFrameTreeNodeInfo, frame_tree_node);
129
Harkiran Bolaria5c5a97392022-03-10 14:18:50130 if (features::GetBrowsingContextMode() ==
131 features::BrowsingContextStateImplementationType::
132 kLegacyOneToOneWithFrameTreeNode) {
133 DCHECK_EQ(this,
134 frame_tree_node->current_frame_host()->browsing_context_state());
135 }
136
137 if (features::GetBrowsingContextMode() ==
Harkiran Bolariae45272d2022-04-12 08:05:01138 features::BrowsingContextStateImplementationType::
139 kSwapForCrossBrowsingInstanceNavigations &&
140 proxy_access_mode == ProxyAccessMode::kRegular) {
Harkiran Bolaria5c5a97392022-03-10 14:18:50141 // See comments in GetRenderFrameProxyHost for why this check is needed.
Camille Lamyc9351922025-05-01 02:57:44142 CHECK_EQ(browsing_instance_id_.value(),
143 site_instance_group->browsing_instance_id());
Harkiran Bolaria5c5a97392022-03-10 14:18:50144 }
145
Sharon Yangdcc5f252024-05-09 18:27:23146 auto site_instance_group_id = site_instance_group->GetId();
Harkiran Bolaria5c5a97392022-03-10 14:18:50147 CHECK(proxy_hosts_.find(site_instance_group_id) == proxy_hosts_.end())
148 << "A proxy already existed for this SiteInstanceGroup.";
Dave Tapuska144570102022-08-02 19:28:27149 RenderFrameProxyHost* proxy_host = new RenderFrameProxyHost(
Sharon Yangdcc5f252024-05-09 18:27:23150 site_instance_group, std::move(rvh), frame_tree_node, frame_token);
Harkiran Bolaria5c5a97392022-03-10 14:18:50151 proxy_hosts_[site_instance_group_id] = base::WrapUnique(proxy_host);
Sharon Yangdcc5f252024-05-09 18:27:23152 site_instance_group->AddObserver(this);
Harkiran Bolaria5c5a97392022-03-10 14:18:50153
Harkiran Bolariaa8347782022-04-06 09:25:11154 TRACE_EVENT_END("navigation", ChromeTrackEvent::kRenderFrameProxyHost,
155 proxy_host);
Harkiran Bolaria5c5a97392022-03-10 14:18:50156 return proxy_host;
157}
158
Harkiran Bolariae45272d2022-04-12 08:05:01159RenderFrameProxyHost* BrowsingContextState::CreateOuterDelegateProxy(
Sharon Yangdcc5f252024-05-09 18:27:23160 SiteInstanceGroup* outer_contents_site_instance_group,
Dave Tapuska144570102022-08-02 19:28:27161 FrameTreeNode* frame_tree_node,
162 const blink::RemoteFrameToken& frame_token) {
Harkiran Bolariae45272d2022-04-12 08:05:01163 // We only get here when Delegate for this manager is an inner delegate.
Sharon Yangdcc5f252024-05-09 18:27:23164 return CreateRenderFrameProxyHost(outer_contents_site_instance_group,
Harkiran Bolariae45272d2022-04-12 08:05:01165 /*rvh=*/nullptr, frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27166 ProxyAccessMode::kAllowOuterDelegate,
167 frame_token);
Harkiran Bolariae45272d2022-04-12 08:05:01168}
169
Harkiran Bolariad22a1dca2022-02-22 17:01:12170size_t BrowsingContextState::GetProxyCount() {
171 return proxy_hosts_.size();
172}
173
Harkiran Bolaria5ce27632022-01-20 15:05:05174bool BrowsingContextState::UpdateFramePolicyHeaders(
175 network::mojom::WebSandboxFlags sandbox_flags,
Sandor Major878f8352025-02-18 20:16:02176 const network::ParsedPermissionsPolicy& parsed_header) {
Harkiran Bolaria5ce27632022-01-20 15:05:05177 bool changed = false;
178 if (replication_state_->permissions_policy_header != parsed_header) {
179 replication_state_->permissions_policy_header = parsed_header;
180 changed = true;
181 }
182 // TODO(iclelland): Kill the renderer if sandbox flags is not a subset of the
183 // currently effective sandbox flags from the frame. https://crbug.com/740556
184 network::mojom::WebSandboxFlags updated_flags =
185 sandbox_flags | replication_state_->frame_policy.sandbox_flags;
186 if (replication_state_->active_sandbox_flags != updated_flags) {
187 replication_state_->active_sandbox_flags = updated_flags;
188 changed = true;
189 }
190 // Notify any proxies if the policies have been changed.
191 if (changed) {
Charlie Reis0650ad0d2024-12-06 18:12:35192 TRACE_EVENT("navigation",
193 "BrowsingContextState::UpdateFramePolicyHeaders broadcast");
Dave Tapuska82b54012022-07-15 23:26:10194 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31195 [this](RenderFrameProxyHost* proxy) {
196 proxy->GetAssociatedRemoteFrame()->DidSetFramePolicyHeaders(
197 replication_state_->active_sandbox_flags,
198 replication_state_->permissions_policy_header);
199 },
Sharon Yang6b5313432023-03-24 05:07:57200 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria5ce27632022-01-20 15:05:05201 }
202 return changed;
203}
204
205bool BrowsingContextState::CommitFramePolicy(
206 const blink::FramePolicy& new_frame_policy) {
207 // Documents create iframes, iframes host new documents. Both are associated
208 // with sandbox flags. They are required to be stricter or equal to their
209 // owner when they change, as we go down.
Alison Gale81f4f2c72024-04-22 19:33:31210 // TODO(crbug.com/40202483). Enforce the invariant mentioned above,
Harkiran Bolaria5ce27632022-01-20 15:05:05211 // once the interactions with fenced frame has been tested and clarified.
212
213 bool did_change_flags = new_frame_policy.sandbox_flags !=
214 replication_state_->frame_policy.sandbox_flags;
215 bool did_change_container_policy =
216 new_frame_policy.container_policy !=
217 replication_state_->frame_policy.container_policy;
218 bool did_change_required_document_policy =
219 new_frame_policy.required_document_policy !=
220 replication_state_->frame_policy.required_document_policy;
Harkiran Bolaria5ce27632022-01-20 15:05:05221
Harkiran Bolaria4eacb3a2021-12-13 20:03:47222 if (did_change_flags) {
223 replication_state_->frame_policy.sandbox_flags =
224 new_frame_policy.sandbox_flags;
225 }
226 if (did_change_container_policy) {
227 replication_state_->frame_policy.container_policy =
228 new_frame_policy.container_policy;
229 }
230 if (did_change_required_document_policy) {
231 replication_state_->frame_policy.required_document_policy =
232 new_frame_policy.required_document_policy;
233 }
Harkiran Bolariae3521432021-12-14 11:27:43234
Harkiran Bolaria5ce27632022-01-20 15:05:05235 UpdateFramePolicyHeaders(new_frame_policy.sandbox_flags,
236 replication_state_->permissions_policy_header);
237 return did_change_flags || did_change_container_policy ||
238 did_change_required_document_policy;
Harkiran Bolaria7fdb4c642021-12-20 12:47:00239}
240
Harkiran Bolaria880a7632022-02-28 16:02:50241void BrowsingContextState::SetFrameName(const std::string& name,
242 const std::string& unique_name) {
243 if (name == replication_state_->name) {
244 // |unique_name| shouldn't change unless |name| changes.
245 DCHECK_EQ(unique_name, replication_state_->unique_name);
246 return;
247 }
248
249 if (parent_) {
250 // Non-main frames should have a non-empty unique name.
251 DCHECK(!unique_name.empty());
252 } else {
253 // Unique name of main frames should always stay empty.
254 DCHECK(unique_name.empty());
255 }
256
257 // Note the unique name should only be able to change before the first real
258 // load is committed, but that's not strongly enforced here.
Charlie Reis0650ad0d2024-12-06 18:12:35259 {
260 TRACE_EVENT("navigation", "BrowsingContextState::SetFrameName broadcast",
261 "name", name, "unique_name", unique_name);
262 ExecuteRemoteFramesBroadcastMethod(
263 [&name, &unique_name](RenderFrameProxyHost* proxy) {
264 proxy->GetAssociatedRemoteFrame()->SetReplicatedName(name,
265 unique_name);
266 },
267 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
268 }
Harkiran Bolaria880a7632022-02-28 16:02:50269 replication_state_->unique_name = unique_name;
270 replication_state_->name = name;
271}
272
Harkiran Bolariae3521432021-12-14 11:27:43273void BrowsingContextState::SetCurrentOrigin(
274 const url::Origin& origin,
275 bool is_potentially_trustworthy_unique_origin) {
276 if (origin.IsSameOriginWith(replication_state_->origin) &&
277 replication_state_->has_potentially_trustworthy_unique_origin ==
278 is_potentially_trustworthy_unique_origin) {
279 return;
280 }
281
Charlie Reis0650ad0d2024-12-06 18:12:35282 {
283 TRACE_EVENT("navigation",
284 "BrowsingContextState::SetCurrentOrigin broadcast", "origin",
285 origin);
286 ExecuteRemoteFramesBroadcastMethod(
287 [&origin, is_potentially_trustworthy_unique_origin](
288 RenderFrameProxyHost* proxy) {
289 proxy->GetAssociatedRemoteFrame()->SetReplicatedOrigin(
290 origin, is_potentially_trustworthy_unique_origin);
291 },
292 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
293 }
Harkiran Bolariae3521432021-12-14 11:27:43294
295 replication_state_->origin = origin;
296 replication_state_->has_potentially_trustworthy_unique_origin =
297 is_potentially_trustworthy_unique_origin;
298}
299
300void BrowsingContextState::SetInsecureRequestPolicy(
301 blink::mojom::InsecureRequestPolicy policy) {
302 if (policy == replication_state_->insecure_request_policy)
303 return;
Charlie Reis0650ad0d2024-12-06 18:12:35304 {
305 TRACE_EVENT("navigation",
306 "BrowsingContextState::SetInsecureRequestPolicy broadcast");
307 ExecuteRemoteFramesBroadcastMethod(
308 [policy](RenderFrameProxyHost* proxy) {
309 proxy->GetAssociatedRemoteFrame()->EnforceInsecureRequestPolicy(
310 policy);
311 },
312 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
313 }
Harkiran Bolariae3521432021-12-14 11:27:43314 replication_state_->insecure_request_policy = policy;
315}
316
317void BrowsingContextState::SetInsecureNavigationsSet(
318 const std::vector<uint32_t>& insecure_navigations_set) {
319 DCHECK(std::is_sorted(insecure_navigations_set.begin(),
320 insecure_navigations_set.end()));
321 if (insecure_navigations_set == replication_state_->insecure_navigations_set)
322 return;
Charlie Reis0650ad0d2024-12-06 18:12:35323 {
324 TRACE_EVENT("navigation",
325 "BrowsingContextState::SetInsecureNavigationsSet broadcast");
326 ExecuteRemoteFramesBroadcastMethod(
327 [&insecure_navigations_set](RenderFrameProxyHost* proxy) {
328 proxy->GetAssociatedRemoteFrame()->EnforceInsecureNavigationsSet(
329 insecure_navigations_set);
330 },
331 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
332 }
Harkiran Bolariae3521432021-12-14 11:27:43333 replication_state_->insecure_navigations_set = insecure_navigations_set;
334}
335
336void BrowsingContextState::OnSetHadStickyUserActivationBeforeNavigation(
337 bool value) {
Charlie Reis0650ad0d2024-12-06 18:12:35338 {
339 TRACE_EVENT("navigation",
340 "BrowsingContextState::"
341 "OnSetHadStickyUserActivationBeforeNavigation broadcast",
342 "value", value);
343 ExecuteRemoteFramesBroadcastMethod(
344 [value](RenderFrameProxyHost* proxy) {
345 proxy->GetAssociatedRemoteFrame()
346 ->SetHadStickyUserActivationBeforeNavigation(value);
347 },
348 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
349 }
Harkiran Bolariae3521432021-12-14 11:27:43350 replication_state_->has_received_user_gesture_before_nav = value;
351}
352
David Bokanfa230cc2022-07-22 18:02:33353void BrowsingContextState::SetIsAdFrame(bool is_ad_frame) {
354 if (is_ad_frame == replication_state_->is_ad_frame)
Harkiran Bolariae3521432021-12-14 11:27:43355 return;
356
David Bokanfa230cc2022-07-22 18:02:33357 replication_state_->is_ad_frame = is_ad_frame;
Charlie Reis0650ad0d2024-12-06 18:12:35358 {
359 TRACE_EVENT("navigation", "BrowsingContextState::SetIsAdFrame broadcast",
360 "is_ad_frame", is_ad_frame);
361 ExecuteRemoteFramesBroadcastMethod(
362 [is_ad_frame](RenderFrameProxyHost* proxy) {
363 proxy->GetAssociatedRemoteFrame()->SetReplicatedIsAdFrame(
364 is_ad_frame);
365 },
366 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
367 }
Harkiran Bolariae3521432021-12-14 11:27:43368}
369
Harkiran Bolariae182a5942021-12-20 17:23:31370void BrowsingContextState::ActiveFrameCountIsZero(
Sharon Yanga2fe85e2022-02-09 21:38:29371 SiteInstanceGroup* site_instance_group) {
Sharon Yang417a5df2024-04-23 17:57:15372 CheckIfSiteInstanceGroupIsUnused(site_instance_group, kActiveFrameCount);
373}
374
375void BrowsingContextState::KeepAliveCountIsZero(
376 SiteInstanceGroup* site_instance_group) {
377 CheckIfSiteInstanceGroupIsUnused(site_instance_group, kKeepAliveCount);
378}
379
380void BrowsingContextState::CheckIfSiteInstanceGroupIsUnused(
381 SiteInstanceGroup* site_instance_group,
382 RefCountType ref_count_type) {
383 // Only delete the proxy if both counts are zero.
384 if (site_instance_group->keep_alive_count() > 0 ||
385 site_instance_group->active_frame_count() > 0) {
386 return;
387 }
388
389 // |site_instance_group| no longer contains any active RenderFrameHosts or
390 // NavigationStateKeepAlive objects, so we don't need to maintain a proxy
391 // there anymore.
Sharon Yanga2fe85e2022-02-09 21:38:29392 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31393 CHECK(proxy);
394
Sharon Yang417a5df2024-04-23 17:57:15395 if (kActiveFrameCount) {
396 TRACE_EVENT_INSTANT("navigation",
397 "BrowsingContextState::ActiveFrameCountIsZero",
398 ChromeTrackEvent::kBrowsingContextState, this,
399 ChromeTrackEvent::kRenderFrameProxyHost, proxy);
400 } else if (kKeepAliveCount) {
401 TRACE_EVENT_INSTANT("navigation",
402 "BrowsingContextState::KeepAliveCountIsZero",
403 ChromeTrackEvent::kBrowsingContextState, this,
404 ChromeTrackEvent::kRenderFrameProxyHost, proxy);
405 }
Harkiran Bolariaa8347782022-04-06 09:25:11406
Sharon Yanga2fe85e2022-02-09 21:38:29407 DeleteRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31408}
409
410void BrowsingContextState::RenderProcessGone(
Sharon Yanga2fe85e2022-02-09 21:38:29411 SiteInstanceGroup* site_instance_group,
Harkiran Bolariae182a5942021-12-20 17:23:31412 const ChildProcessTerminationInfo& info) {
Harkiran Bolariae45272d2022-04-12 08:05:01413 GetRenderFrameProxyHost(site_instance_group,
414 ProxyAccessMode::kAllowOuterDelegate)
Sharon Yanga2fe85e2022-02-09 21:38:29415 ->SetRenderFrameProxyCreated(false);
Harkiran Bolariae182a5942021-12-20 17:23:31416}
417
Harkiran Bolaria5ce27632022-01-20 15:05:05418void BrowsingContextState::SendFramePolicyUpdatesToProxies(
Sharon Yang571baee2022-03-18 19:01:54419 SiteInstanceGroup* parent_group,
Harkiran Bolaria5ce27632022-01-20 15:05:05420 const blink::FramePolicy& frame_policy) {
421 // Notify all of the frame's proxies about updated policies, excluding
422 // the parent process since it already knows the latest state.
Charlie Reis0650ad0d2024-12-06 18:12:35423 TRACE_EVENT(
424 "navigation",
425 "BrowsingContextState::SendFramePolicyUpdatesToProxies broadcast");
Dave Tapuska82b54012022-07-15 23:26:10426 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31427 [parent_group, &frame_policy](RenderFrameProxyHost* proxy) {
428 if (proxy->site_instance_group() == parent_group) {
429 return;
430 }
431 proxy->GetAssociatedRemoteFrame()->DidUpdateFramePolicy(frame_policy);
432 },
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() {
Charlie Reis0650ad0d2024-12-06 18:12:35437 TRACE_EVENT("navigation",
438 "BrowsingContextState::OnDidStartLoading broadcast");
Dave Tapuska82b54012022-07-15 23:26:10439 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31440 [](RenderFrameProxyHost* proxy) {
Dave Tapuska82b54012022-07-15 23:26:10441 proxy->GetAssociatedRemoteFrame()->DidStartLoading();
Kevin McNee7705fe82024-11-07 18:56:31442 },
Sharon Yang6b5313432023-03-24 05:07:57443 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40444}
445
446void BrowsingContextState::OnDidStopLoading() {
Charlie Reis0650ad0d2024-12-06 18:12:35447 TRACE_EVENT("navigation", "BrowsingContextState::OnDidStopLoading broadcast");
Dave Tapuska82b54012022-07-15 23:26:10448 ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31449 [](RenderFrameProxyHost* proxy) {
Dave Tapuska82b54012022-07-15 23:26:10450 proxy->GetAssociatedRemoteFrame()->DidStopLoading();
Kevin McNee7705fe82024-11-07 18:56:31451 },
Sharon Yang6b5313432023-03-24 05:07:57452 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
Harkiran Bolaria3f83fba72022-03-10 17:48:40453}
454
Harkiran Bolaria0b3bdef02022-03-10 13:04:40455void BrowsingContextState::ResetProxyHosts() {
456 for (const auto& pair : proxy_hosts_) {
457 pair.second->site_instance_group()->RemoveObserver(this);
458 }
459 proxy_hosts_.clear();
460}
461
Sharon Yang571baee2022-03-18 19:01:54462void BrowsingContextState::UpdateOpener(
463 SiteInstanceGroup* source_site_instance_group) {
Harkiran Bolaria3f83fba72022-03-10 17:48:40464 for (const auto& pair : proxy_hosts_) {
Sharon Yang571baee2022-03-18 19:01:54465 if (pair.second->site_instance_group() == source_site_instance_group)
Harkiran Bolaria3f83fba72022-03-10 17:48:40466 continue;
467 pair.second->UpdateOpener();
468 }
469}
470
471void BrowsingContextState::OnDidUpdateFrameOwnerProperties(
472 const blink::mojom::FrameOwnerProperties& properties) {
473 // Notify this frame's proxies if they live in a different process from its
474 // parent. This is only currently needed for the allowFullscreen property,
475 // since that can be queried on RemoteFrame ancestors.
476 //
477 // TODO(alexmos): It would be sufficient to only send this update to proxies
478 // in the current FrameTree.
Kevin McNee7705fe82024-11-07 18:56:31479 SiteInstanceGroup* parent_group = parent_->GetSiteInstance()->group();
Charlie Reis0650ad0d2024-12-06 18:12:35480 {
481 TRACE_EVENT(
482 "navigation",
483 "BrowsingContextState::OnDidUpdateFrameOwnerProperties broadcast");
484 ExecuteRemoteFramesBroadcastMethod(
485 [parent_group, &properties](RenderFrameProxyHost* proxy) {
486 if (proxy->site_instance_group() == parent_group) {
487 return;
488 }
489 proxy->GetAssociatedRemoteFrame()->SetFrameOwnerProperties(
490 properties.Clone());
491 },
492 /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr);
493 }
Harkiran Bolaria3f83fba72022-03-10 17:48:40494}
495
496void BrowsingContextState::ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31497 base::FunctionRef<void(RenderFrameProxyHost*)> callback,
Sharon Yang6b5313432023-03-24 05:07:57498 SiteInstanceGroup* group_to_skip,
Harkiran Bolaria3f83fba72022-03-10 17:48:40499 RenderFrameProxyHost* outer_delegate_proxy) {
Charlie Reis0650ad0d2024-12-06 18:12:35500 TRACE_EVENT("navigation",
501 "BrowsingContextState::ExecuteRemoteFramesBroadcastMethod");
Harkiran Bolaria3f83fba72022-03-10 17:48:40502 for (const auto& pair : proxy_hosts_) {
503 if (outer_delegate_proxy == pair.second.get())
504 continue;
Sharon Yang6b5313432023-03-24 05:07:57505 if (pair.second->site_instance_group() == group_to_skip) {
Harkiran Bolaria3f83fba72022-03-10 17:48:40506 continue;
Sharon Yang6b5313432023-03-24 05:07:57507 }
Harkiran Bolaria3f83fba72022-03-10 17:48:40508 if (!pair.second->is_render_frame_proxy_live())
509 continue;
Kevin McNee7705fe82024-11-07 18:56:31510 callback(pair.second.get());
Harkiran Bolaria3f83fba72022-03-10 17:48:40511 }
512}
513
Harkiran Bolaria3bf5457f2022-03-10 20:04:37514void BrowsingContextState::WriteIntoTrace(
Alexander Timin074cd182022-03-23 18:11:22515 perfetto::TracedProto<TraceProto> proto) const {
Arthur Hemery08d82882023-04-27 12:33:14516 if (browsing_instance_id_.has_value()) {
Harkiran Bolaria3bf5457f2022-03-10 20:04:37517 proto->set_browsing_instance_id(browsing_instance_id_.value().value());
Arthur Hemery08d82882023-04-27 12:33:14518 }
519
Alexander Timin074cd182022-03-23 18:11:22520 perfetto::TracedDictionary dict = std::move(proto).AddDebugAnnotations();
521 dict.Add("this", static_cast<const void*>(this));
Harkiran Bolaria3bf5457f2022-03-10 20:04:37522}
523
Harkiran Bolaria875d4f62022-05-17 16:18:23524base::SafeRef<BrowsingContextState> BrowsingContextState::GetSafeRef() {
525 return weak_factory_.GetSafeRef();
526}
527
Alexander Timin07cad0762022-03-15 00:33:17528} // namespace content