blob: 2788dfd528587f18dcad80ad682c99be251f2afc [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#ifndef CONTENT_BROWSER_RENDERER_HOST_BROWSING_CONTEXT_STATE_H_
6#define CONTENT_BROWSER_RENDERER_HOST_BROWSING_CONTEXT_STATE_H_
7
David Sandersaad78202022-01-23 02:13:298#include "base/feature_list.h"
Kevin McNee7705fe82024-11-07 18:56:319#include "base/functional/function_ref.h"
Harkiran Bolaria8dec6f92021-12-07 14:57:1210#include "base/memory/ref_counted.h"
Harkiran Bolaria875d4f62022-05-17 16:18:2311#include "base/memory/safe_ref.h"
Arthur Hemerya3e593f2023-05-11 17:15:5712#include "base/unguessable_token.h"
Harkiran Bolaria8dec6f92021-12-07 14:57:1213#include "content/browser/renderer_host/render_frame_proxy_host.h"
14#include "content/browser/site_instance_group.h"
Arthur Hemeryc2f98e3d2022-10-03 15:37:2615#include "content/public/browser/browsing_instance_id.h"
Sandor Major878f8352025-02-18 20:16:0216#include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h"
Harkiran Bolaria8dec6f92021-12-07 14:57:1217#include "third_party/blink/public/mojom/frame/frame_replication_state.mojom-forward.h"
Harkiran Bolaria3bf5457f2022-03-10 20:04:3718#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
Harkiran Bolaria8dec6f92021-12-07 14:57:1219
20namespace features {
21// Currently there are two paths - legacy code, in which BrowsingContextState
22// will be 1:1 with FrameTreeNode, allowing us to move proxy storage to it as a
23// no-op, and a new path hidden behind a feature flag, which will create a new
24// BrowsingContextState for cross-BrowsingInstance navigations.
25
26CONTENT_EXPORT extern const base::Feature
27 kNewBrowsingContextStateOnBrowsingContextGroupSwap;
28
29enum class BrowsingContextStateImplementationType {
30 kLegacyOneToOneWithFrameTreeNode,
31 kSwapForCrossBrowsingInstanceNavigations,
32};
33
34CONTENT_EXPORT BrowsingContextStateImplementationType GetBrowsingContextMode();
35} // namespace features
36
37namespace content {
38
David Sanders73ebb80c2022-04-19 00:53:1239class RenderFrameHostImpl;
40
Harkiran Bolaria8dec6f92021-12-07 14:57:1241// BrowsingContextState is intended to store all state associated with a given
42// browsing context (BrowsingInstance in the code, as defined in the HTML spec
43// (https://html.spec.whatwg.org/multipage/browsers.html#browsing-context),
44// in particular RenderFrameProxyHosts and FrameReplicationState. Each
45// RenderFrameHost will have an associated BrowsingContextState (which never
46// changes), but each BrowsingContextState can be shared between multiple
47// RenderFrameHosts for the same frame/FrameTreeNode.
48
Harkiran Bolaria2912a6b32022-02-22 16:43:4549// BrowsingContextState is responsible for proxy storage and
50// RenderFrameHostManager is responsible for connecting different
51// BrowsingContextStates and creating proxies for appropriate SiteInstances.
52
Harkiran Bolaria8dec6f92021-12-07 14:57:1253// A new BCS will be created when a new RenderFrameHost is created for a new
54// frame or a speculative RFH is created for a cross-BrowsingInstance (browsing
55// context group in the spec) navigation (speculative RFHs created in the same
56// BrowsingInstance will use the same BrowsingContextState as the old
57// RenderFrameHost). For pages stored in bfcache and used for prerendering
58// activations, BrowsingContextState will travel automatically together with the
59// RenderFrameHost.
60
61// Note: "browsing context" is an HTML spec term (close to a "frame") and it's
62// different from content::BrowserContext, which represents a "browser profile".
63
Alison Gale770f3fc2024-04-27 00:39:5864// TODO(crbug.com/40205442): Currently it's under implementation and there are
Harkiran Bolaria8dec6f92021-12-07 14:57:1265// two different modes, controlled by a flag: kLegacyOneToOneWithFrameTreeNode,
Harkiran Bolaria812f22872021-12-08 13:34:5066// where BrowsingContextState is 1:1 with FrameTreeNode and exists for the
67// duration of the FrameTreeNode lifetime, and
Harkiran Bolaria8dec6f92021-12-07 14:57:1268// kSwapForCrossBrowsingInstanceNavigations intended state with the behaviour
Harkiran Bolaria812f22872021-12-08 13:34:5069// described above, tied to the lifetime of the RenderFrameHostImpl.
70// kLegacyOneToOneWithFrameTreeNode is currently enabled and will be removed
71// once the functionality gated behind kSwapForCrossBrowsingInstanceNavigations
72// is implemented.
Harkiran Bolariad22a1dca2022-02-22 17:01:1273class CONTENT_EXPORT BrowsingContextState
74 : public base::RefCounted<BrowsingContextState>,
75 public SiteInstanceGroup::Observer {
Harkiran Bolaria8dec6f92021-12-07 14:57:1276 public:
Harkiran Bolaria812f22872021-12-08 13:34:5077 using RenderFrameProxyHostMap =
78 std::unordered_map<SiteInstanceGroupId,
Devon Loehr92631c892025-01-02 20:15:1579 std::unique_ptr<RenderFrameProxyHost>>;
Harkiran Bolaria812f22872021-12-08 13:34:5080
Camille Lamyc9351922025-05-01 02:57:4481 // Currently `browsing_instance_id` will be null iff the legacy mode is
82 // enabled, as the legacy mode BrowsingContextState is 1:1 with FrameTreeNode
83 // and therefore doesn't have a dedicated associated BrowsingInstance.
84 // TODO(crbug.com/40205442): Make `browsing_instance_id` non-optional when the
85 // legacy path is removed.
86 BrowsingContextState(blink::mojom::FrameReplicationStatePtr replication_state,
87 RenderFrameHostImpl* parent,
88 std::optional<BrowsingInstanceId> browsing_instance_id);
Harkiran Bolaria8dec6f92021-12-07 14:57:1289
Harkiran Bolaria812f22872021-12-08 13:34:5090 // Returns a const reference to the map of proxy hosts. The keys are
91 // SiteInstanceGroup IDs, the values are RenderFrameProxyHosts.
92 const RenderFrameProxyHostMap& proxy_hosts() const { return proxy_hosts_; }
93
94 RenderFrameProxyHostMap& proxy_hosts() { return proxy_hosts_; }
95
Harkiran Bolaria57e2b062022-03-14 10:27:5896 // Returns true if this is a main BrowsingContextState. True if and only if
97 // this BrowsingContextState doesn't have a parent.
98 bool is_main_frame() const { return !parent_; }
99
Harkiran Bolaria4eacb3a2021-12-13 20:03:47100 const blink::mojom::FrameReplicationState& current_replication_state() const {
101 return *replication_state_;
102 }
103
104 const std::string& frame_name() const { return replication_state_->name; }
105
106 // Returns the currently active frame policy for this frame, including the
107 // sandbox flags which were present at the time the document was loaded, and
108 // the permissions policy container policy, which is set by the iframe's
109 // allowfullscreen, allowpaymentrequest, and allow attributes, along with the
110 // origin of the iframe's src attribute (which may be different from the URL
111 // of the document currently loaded into the frame). This does not include
112 // policy changes that have been made by updating the containing iframe
113 // element attributes since the frame was last navigated; use
114 // pending_frame_policy() for those.
115 const blink::FramePolicy& effective_frame_policy() const {
116 return replication_state_->frame_policy;
117 }
118
119 // Returns the sandbox flags currently in effect for this frame. This includes
120 // flags inherited from parent frames, the currently active flags from the
121 // <iframe> element hosting this frame, as well as any flags set from a
122 // Content-Security-Policy HTTP header. This does not include flags that have
123 // have been updated in an <iframe> element but have not taken effect yet; use
124 // pending_frame_policy() for those. To see the flags which will take effect
125 // on navigation (which does not include the CSP-set flags), use
126 // effective_frame_policy().
127 network::mojom::WebSandboxFlags active_sandbox_flags() const {
128 return replication_state_->active_sandbox_flags;
129 }
130
131 void set_frame_name(const std::string& unique_name, const std::string& name) {
132 replication_state_->unique_name = unique_name;
133 replication_state_->name = name;
134 }
135
Harkiran Bolaria4eacb3a2021-12-13 20:03:47136 void set_has_active_user_gesture(bool has_active_user_gesture) {
137 replication_state_->has_active_user_gesture = has_active_user_gesture;
138 }
139
Harkiran Bolariae45272d2022-04-12 08:05:01140 // All proxies except outer delegate proxies should belong to the same
Camille Lamyc9351922025-05-01 02:57:44141 // BrowsingInstance as their BrowsingContextState.
Arthur Hemery08d82882023-04-27 12:33:14142 //
143 // When kSwapForCrossBrowsingInstanceNavigations is enabled, we might change
144 // BrowsingContextState during a navigation. To ensure that we haven't mixed
Camille Lamyc9351922025-05-01 02:57:44145 // up things, we CHECK that proxies are in the same BrowsingInstance. We do
146 // this CHECK in all functions for creating, deleting, and accessing proxies.
147 // See BrowsingContextState::GetRenderFrameProxyHostImpl() for an example.
Arthur Hemery08d82882023-04-27 12:33:14148 //
149 // When we expect to be in one the exception cases we specify it via the
150 // ProxyAccessMode enum below, which will disable the CHECKs.
Harkiran Bolariae45272d2022-04-12 08:05:01151 enum class ProxyAccessMode {
152 kRegular,
153 kAllowOuterDelegate,
154 };
155
Harkiran Bolaria7fdb4c642021-12-20 12:47:00156 RenderFrameProxyHost* GetRenderFrameProxyHost(
Harkiran Bolariae45272d2022-04-12 08:05:01157 SiteInstanceGroup* site_instance_group,
158 ProxyAccessMode proxy_access_mode = ProxyAccessMode::kRegular) const;
Harkiran Bolaria7fdb4c642021-12-20 12:47:00159
Harkiran Bolariad22a1dca2022-02-22 17:01:12160 // Returns the number of RenderFrameProxyHosts for this frame.
161 size_t GetProxyCount();
162
Harkiran Bolaria880a7632022-02-28 16:02:50163 // Set the current name and notify proxies about the update.
164 void SetFrameName(const std::string& name, const std::string& unique_name);
165
Harkiran Bolariae3521432021-12-14 11:27:43166 // Set the current origin and notify proxies about the update.
167 void SetCurrentOrigin(const url::Origin& origin,
168 bool is_potentially_trustworthy_unique_origin);
169
170 // Sets the current insecure request policy, and notifies proxies about the
171 // update.
172 void SetInsecureRequestPolicy(blink::mojom::InsecureRequestPolicy policy);
173
174 // Sets the current set of insecure urls to upgrade, and notifies proxies
175 // about the update.
176 void SetInsecureNavigationsSet(
177 const std::vector<uint32_t>& insecure_navigations_set);
178
Harkiran Bolaria5ce27632022-01-20 15:05:05179 // Sets the sticky user activation status and notifies proxies about the
Harkiran Bolariae3521432021-12-14 11:27:43180 // update.
181 void OnSetHadStickyUserActivationBeforeNavigation(bool value);
182
David Bokanfa230cc2022-07-22 18:02:33183 // Sets whether this is an ad frame and notifies the proxies about the update.
184 void SetIsAdFrame(bool is_ad_frame);
Harkiran Bolariae3521432021-12-14 11:27:43185
Harkiran Bolariae182a5942021-12-20 17:23:31186 // Delete a RenderFrameProxyHost owned by this object.
Harkiran Bolariae45272d2022-04-12 08:05:01187 void DeleteRenderFrameProxyHost(
188 SiteInstanceGroup* site_instance_group,
189 ProxyAccessMode proxy_access_mode = ProxyAccessMode::kRegular);
Harkiran Bolariae182a5942021-12-20 17:23:31190
Sharon Yanga2fe85e2022-02-09 21:38:29191 // SiteInstanceGroup::Observer
192 void ActiveFrameCountIsZero(SiteInstanceGroup* site_instance_group) override;
Sharon Yang417a5df2024-04-23 17:57:15193 void KeepAliveCountIsZero(SiteInstanceGroup* site_instance_group) override;
Sharon Yanga2fe85e2022-02-09 21:38:29194 void RenderProcessGone(SiteInstanceGroup* site_instance_group,
Harkiran Bolariae182a5942021-12-20 17:23:31195 const ChildProcessTerminationInfo& info) override;
196
Harkiran Bolaria5ce27632022-01-20 15:05:05197 // Set the frame_policy provided in function parameter as active frame policy,
198 // while leaving the FrameTreeNode::pending_frame_policy_ untouched. This
199 // functionality is used on FrameTreeNode initialization, where it is
200 // associated with a RenderFrameHost. Returns a boolean indicating whether
201 // there was an update to the FramePolicy.
202 bool CommitFramePolicy(const blink::FramePolicy& frame_policy);
203
204 // Updates the active sandbox flags in this frame, in response to a
205 // Content-Security-Policy header adding additional flags, in addition to
206 // those given to this frame by its parent, or in response to the
207 // Permissions-Policy header being set. Usually this will be when we create
208 // WebContents with an opener. Note that on navigation, these updates will be
209 // cleared, and the flags in the pending frame policy will be applied to the
210 // frame. The old document's frame policy should therefore not impact the new
211 // document's frame policy.
212 // Returns true iff this operation has changed state of either sandbox flags
213 // or permissions policy.
214 bool UpdateFramePolicyHeaders(
215 network::mojom::WebSandboxFlags sandbox_flags,
Sandor Major878f8352025-02-18 20:16:02216 const network::ParsedPermissionsPolicy& parsed_header);
Harkiran Bolaria5ce27632022-01-20 15:05:05217
218 // Notify all of the proxies about the updated FramePolicy, excluding the
219 // parent, as it will already know.
Sharon Yang571baee2022-03-18 19:01:54220 void SendFramePolicyUpdatesToProxies(SiteInstanceGroup* parent_group,
Harkiran Bolaria5ce27632022-01-20 15:05:05221 const blink::FramePolicy& frame_policy);
222
Harkiran Bolaria2912a6b32022-02-22 16:43:45223 // Create a RenderFrameProxyHost owned by this object. This
Sharon Yangdcc5f252024-05-09 18:27:23224 // RenderFrameProxyHost represents the browsing context in this
225 // SiteInstanceGroup.
Alison Gale770f3fc2024-04-27 00:39:58226 // TODO(crbug.com/40205442): Currently we pass a FrameTreeNode because it is
Harkiran Bolaria2912a6b32022-02-22 16:43:45227 // required for the constructor to RenderFrameProxyHost. However, the stored
228 // reference to FrameTreeNode should be replaced by a BrowsingContextState
229 // instead; FrameTreeNode will need to be removed from here as well.
230 RenderFrameProxyHost* CreateRenderFrameProxyHost(
Sharon Yangdcc5f252024-05-09 18:27:23231 SiteInstanceGroup* site_instance_group,
Harkiran Bolaria2912a6b32022-02-22 16:43:45232 const scoped_refptr<RenderViewHostImpl>& rvh,
Harkiran Bolariae45272d2022-04-12 08:05:01233 FrameTreeNode* frame_tree_node,
Dave Tapuska144570102022-08-02 19:28:27234 ProxyAccessMode proxy_access_mode = ProxyAccessMode::kRegular,
235 const blink::RemoteFrameToken& frame_token = blink::RemoteFrameToken());
Harkiran Bolariae45272d2022-04-12 08:05:01236
237 // Called on the RFHM of the inner WebContents to create a
Sharon Yangdcc5f252024-05-09 18:27:23238 // RenderFrameProxyHost in its outer WebContents' SiteInstanceGroup,
239 // |outer_contents_site_instance_group|.
Harkiran Bolariae45272d2022-04-12 08:05:01240 RenderFrameProxyHost* CreateOuterDelegateProxy(
Sharon Yangdcc5f252024-05-09 18:27:23241 SiteInstanceGroup* outer_contents_site_instance_group,
Dave Tapuska144570102022-08-02 19:28:27242 FrameTreeNode* frame_tree_node,
243 const blink::RemoteFrameToken& frame_token);
Harkiran Bolaria2912a6b32022-02-22 16:43:45244
Harkiran Bolaria0b3bdef02022-03-10 13:04:40245 // Deletes any proxy hosts associated with this node. Used during destruction
246 // of WebContentsImpl.
247 void ResetProxyHosts();
248
Harkiran Bolaria3f83fba72022-03-10 17:48:40249 // Notification methods to tell this RenderFrameHostManager that the frame it
250 // is responsible for has started or stopped loading a document.
251 void OnDidStartLoading();
252 void OnDidStopLoading();
253
254 // Notify proxies that an opener has been updated.
Sharon Yang571baee2022-03-18 19:01:54255 void UpdateOpener(SiteInstanceGroup* source_site_instance_group);
Harkiran Bolaria3f83fba72022-03-10 17:48:40256
257 void OnDidUpdateFrameOwnerProperties(
258 const blink::mojom::FrameOwnerProperties& properties);
259
260 void ExecuteRemoteFramesBroadcastMethod(
Kevin McNee7705fe82024-11-07 18:56:31261 base::FunctionRef<void(RenderFrameProxyHost*)> callback,
Sharon Yang6b5313432023-03-24 05:07:57262 SiteInstanceGroup* group_to_skip,
Harkiran Bolaria3f83fba72022-03-10 17:48:40263 RenderFrameProxyHost* outer_delegate_proxy);
264
Alexander Timin074cd182022-03-23 18:11:22265 using TraceProto = perfetto::protos::pbzero::BrowsingContextState;
266 // Write a representation of this object into a trace.
267 void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const;
Harkiran Bolaria3bf5457f2022-03-10 20:04:37268
Harkiran Bolaria875d4f62022-05-17 16:18:23269 base::SafeRef<BrowsingContextState> GetSafeRef();
270
Harkiran Bolaria8dec6f92021-12-07 14:57:12271 protected:
272 friend class base::RefCounted<BrowsingContextState>;
273
Sharon Yang98309fb12023-07-28 00:11:40274 ~BrowsingContextState() override;
Harkiran Bolaria812f22872021-12-08 13:34:50275
276 private:
Harkiran Bolariaa8347782022-04-06 09:25:11277 RenderFrameProxyHost* GetRenderFrameProxyHostImpl(
Harkiran Bolariae45272d2022-04-12 08:05:01278 SiteInstanceGroup* site_instance_group,
279 ProxyAccessMode proxy_access_mode) const;
Harkiran Bolariaa8347782022-04-06 09:25:11280
Sharon Yang417a5df2024-04-23 17:57:15281 // Helper to check if all refcounts SiteInstanceGroup keeps track of are zero.
282 // Deletes all corresponding proxies if so. RefCountType is for tracing.
283 enum RefCountType {
284 kActiveFrameCount = 0,
285 kKeepAliveCount = 1,
286 };
287 void CheckIfSiteInstanceGroupIsUnused(SiteInstanceGroup* site_instance_group,
288 RefCountType ref_count_type);
289
Harkiran Bolaria2912a6b32022-02-22 16:43:45290 // Proxy hosts for this browsing context in various renderer processes, keyed
291 // by SiteInstanceGroup ID.
Harkiran Bolaria812f22872021-12-08 13:34:50292 RenderFrameProxyHostMap proxy_hosts_;
Harkiran Bolaria4eacb3a2021-12-13 20:03:47293
294 // Track information that needs to be replicated to processes that have
295 // proxies for this frame.
296 blink::mojom::FrameReplicationStatePtr replication_state_;
Harkiran Bolaria880a7632022-02-28 16:02:50297
298 // Parent document of this BrowsingContextState, might be null if this is a
299 // main frame BrowsingContextState.
300 const raw_ptr<RenderFrameHostImpl> parent_;
Harkiran Bolaria0b3bdef02022-03-10 13:04:40301
Camille Lamyc9351922025-05-01 02:57:44302 // ID of the BrowsingInstance to which this BrowsingContextState belongs.
303 // Currently `browsing_instance_id` and will be null iff the legacy mode is
304 // enabled, as the legacy mode BrowsingContextState is 1:1 with FrameTreeNode
305 // and therefore doesn't have a dedicated associated BrowsingInstance.
306 // TODO(crbug.com/40205442): Make `browsing_instance_id` non-optional when the
307 // legacy path is removed.
Arthur Sonzognic686e8f2024-01-11 08:36:37308 const std::optional<BrowsingInstanceId> browsing_instance_id_;
Harkiran Bolaria875d4f62022-05-17 16:18:23309
310 base::WeakPtrFactory<BrowsingContextState> weak_factory_{this};
Harkiran Bolaria8dec6f92021-12-07 14:57:12311};
312
313} // namespace content
314
315#endif // CONTENT_BROWSER_RENDERER_HOST_BROWSING_CONTEXT_STATE_H_