blob: c618d26441fcfb5cb09dd446e1f6b28cc619ab1b [file] [log] [blame]
Harkiran Bolaria8dec6f92021-12-07 14:57:121// Copyright (c) 2021 The Chromium Authors. All rights reserved.
2// 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
Harkiran Bolaria2912a6b32022-02-22 16:43:457#include "content/browser/renderer_host/frame_tree_node.h"
8#include "content/browser/renderer_host/render_view_host_impl.h"
9#include "content/common/content_navigation_policy.h"
Harkiran Bolaria5ce27632022-01-20 15:05:0510#include "services/network/public/cpp/web_sandbox_flags.h"
11#include "services/network/public/mojom/web_sandbox_flags.mojom.h"
12
Harkiran Bolaria8dec6f92021-12-07 14:57:1213namespace features {
14const base::Feature kNewBrowsingContextStateOnBrowsingContextGroupSwap{
15 "NewBrowsingContextStateOnBrowsingContextGroupSwap",
16 base::FEATURE_DISABLED_BY_DEFAULT};
17
18BrowsingContextStateImplementationType GetBrowsingContextMode() {
19 if (base::FeatureList::IsEnabled(
20 kNewBrowsingContextStateOnBrowsingContextGroupSwap)) {
21 return BrowsingContextStateImplementationType::
22 kSwapForCrossBrowsingInstanceNavigations;
23 }
24
25 return BrowsingContextStateImplementationType::
26 kLegacyOneToOneWithFrameTreeNode;
27}
28} // namespace features
29
30namespace content {
31
Harkiran Bolaria4eacb3a2021-12-13 20:03:4732BrowsingContextState::BrowsingContextState(
33 blink::mojom::FrameReplicationStatePtr replication_state)
34 : replication_state_(std::move(replication_state)) {}
Harkiran Bolaria8dec6f92021-12-07 14:57:1235
36BrowsingContextState::~BrowsingContextState() = default;
Harkiran Bolaria4eacb3a2021-12-13 20:03:4737
Harkiran Bolaria5ce27632022-01-20 15:05:0538RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHost(
39 SiteInstanceGroup* site_instance_group) const {
40 auto it = proxy_hosts_.find(site_instance_group->GetId());
41 if (it != proxy_hosts_.end())
42 return it->second.get();
43 return nullptr;
44}
45
Harkiran Bolariad22a1dca2022-02-22 17:01:1246size_t BrowsingContextState::GetProxyCount() {
47 return proxy_hosts_.size();
48}
49
Harkiran Bolaria5ce27632022-01-20 15:05:0550bool BrowsingContextState::UpdateFramePolicyHeaders(
51 network::mojom::WebSandboxFlags sandbox_flags,
52 const blink::ParsedPermissionsPolicy& parsed_header) {
53 bool changed = false;
54 if (replication_state_->permissions_policy_header != parsed_header) {
55 replication_state_->permissions_policy_header = parsed_header;
56 changed = true;
57 }
58 // TODO(iclelland): Kill the renderer if sandbox flags is not a subset of the
59 // currently effective sandbox flags from the frame. https://crbug.com/740556
60 network::mojom::WebSandboxFlags updated_flags =
61 sandbox_flags | replication_state_->frame_policy.sandbox_flags;
62 if (replication_state_->active_sandbox_flags != updated_flags) {
63 replication_state_->active_sandbox_flags = updated_flags;
64 changed = true;
65 }
66 // Notify any proxies if the policies have been changed.
67 if (changed) {
68 for (const auto& pair : proxy_hosts_) {
69 pair.second->GetAssociatedRemoteFrame()->DidSetFramePolicyHeaders(
70 replication_state_->active_sandbox_flags,
71 replication_state_->permissions_policy_header);
72 }
73 }
74 return changed;
75}
76
77bool BrowsingContextState::CommitFramePolicy(
78 const blink::FramePolicy& new_frame_policy) {
79 // Documents create iframes, iframes host new documents. Both are associated
80 // with sandbox flags. They are required to be stricter or equal to their
81 // owner when they change, as we go down.
82 // TODO(https://crbug.com/1262061). Enforce the invariant mentioned above,
83 // once the interactions with fenced frame has been tested and clarified.
84
85 bool did_change_flags = new_frame_policy.sandbox_flags !=
86 replication_state_->frame_policy.sandbox_flags;
87 bool did_change_container_policy =
88 new_frame_policy.container_policy !=
89 replication_state_->frame_policy.container_policy;
90 bool did_change_required_document_policy =
91 new_frame_policy.required_document_policy !=
92 replication_state_->frame_policy.required_document_policy;
93 DCHECK_EQ(new_frame_policy.is_fenced,
94 replication_state_->frame_policy.is_fenced);
95
Harkiran Bolaria4eacb3a2021-12-13 20:03:4796 if (did_change_flags) {
97 replication_state_->frame_policy.sandbox_flags =
98 new_frame_policy.sandbox_flags;
99 }
100 if (did_change_container_policy) {
101 replication_state_->frame_policy.container_policy =
102 new_frame_policy.container_policy;
103 }
104 if (did_change_required_document_policy) {
105 replication_state_->frame_policy.required_document_policy =
106 new_frame_policy.required_document_policy;
107 }
Harkiran Bolariae3521432021-12-14 11:27:43108
Harkiran Bolaria5ce27632022-01-20 15:05:05109 UpdateFramePolicyHeaders(new_frame_policy.sandbox_flags,
110 replication_state_->permissions_policy_header);
111 return did_change_flags || did_change_container_policy ||
112 did_change_required_document_policy;
Harkiran Bolaria7fdb4c642021-12-20 12:47:00113}
114
Harkiran Bolariae3521432021-12-14 11:27:43115void BrowsingContextState::SetCurrentOrigin(
116 const url::Origin& origin,
117 bool is_potentially_trustworthy_unique_origin) {
118 if (origin.IsSameOriginWith(replication_state_->origin) &&
119 replication_state_->has_potentially_trustworthy_unique_origin ==
120 is_potentially_trustworthy_unique_origin) {
121 return;
122 }
123
124 for (const auto& pair : proxy_hosts_) {
125 pair.second->GetAssociatedRemoteFrame()->SetReplicatedOrigin(
126 origin, is_potentially_trustworthy_unique_origin);
127 }
128
129 replication_state_->origin = origin;
130 replication_state_->has_potentially_trustworthy_unique_origin =
131 is_potentially_trustworthy_unique_origin;
132}
133
134void BrowsingContextState::SetInsecureRequestPolicy(
135 blink::mojom::InsecureRequestPolicy policy) {
136 if (policy == replication_state_->insecure_request_policy)
137 return;
138 for (const auto& pair : proxy_hosts_) {
139 pair.second->GetAssociatedRemoteFrame()->EnforceInsecureRequestPolicy(
140 policy);
141 }
142 replication_state_->insecure_request_policy = policy;
143}
144
145void BrowsingContextState::SetInsecureNavigationsSet(
146 const std::vector<uint32_t>& insecure_navigations_set) {
147 DCHECK(std::is_sorted(insecure_navigations_set.begin(),
148 insecure_navigations_set.end()));
149 if (insecure_navigations_set == replication_state_->insecure_navigations_set)
150 return;
151 for (const auto& pair : proxy_hosts_) {
152 pair.second->GetAssociatedRemoteFrame()->EnforceInsecureNavigationsSet(
153 insecure_navigations_set);
154 }
155 replication_state_->insecure_navigations_set = insecure_navigations_set;
156}
157
158void BrowsingContextState::OnSetHadStickyUserActivationBeforeNavigation(
159 bool value) {
160 for (const auto& pair : proxy_hosts_) {
161 pair.second->GetAssociatedRemoteFrame()
162 ->SetHadStickyUserActivationBeforeNavigation(value);
163 }
164 replication_state_->has_received_user_gesture_before_nav = value;
165}
166
167void BrowsingContextState::SetIsAdSubframe(bool is_ad_subframe) {
168 if (is_ad_subframe == replication_state_->is_ad_subframe)
169 return;
170
171 replication_state_->is_ad_subframe = is_ad_subframe;
172 for (const auto& pair : proxy_hosts_) {
173 pair.second->GetAssociatedRemoteFrame()->SetReplicatedIsAdSubframe(
174 is_ad_subframe);
175 }
176}
177
Harkiran Bolariae182a5942021-12-20 17:23:31178void BrowsingContextState::ActiveFrameCountIsZero(
Sharon Yanga2fe85e2022-02-09 21:38:29179 SiteInstanceGroup* site_instance_group) {
180 // |site_instance_group| no longer contains any active RenderFrameHosts, so we
181 // don't need to maintain a proxy there anymore.
182 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31183 CHECK(proxy);
184
Sharon Yanga2fe85e2022-02-09 21:38:29185 DeleteRenderFrameProxyHost(site_instance_group);
Harkiran Bolariae182a5942021-12-20 17:23:31186}
187
188void BrowsingContextState::RenderProcessGone(
Sharon Yanga2fe85e2022-02-09 21:38:29189 SiteInstanceGroup* site_instance_group,
Harkiran Bolariae182a5942021-12-20 17:23:31190 const ChildProcessTerminationInfo& info) {
Sharon Yanga2fe85e2022-02-09 21:38:29191 GetRenderFrameProxyHost(site_instance_group)
192 ->SetRenderFrameProxyCreated(false);
Harkiran Bolariae182a5942021-12-20 17:23:31193}
194
195void BrowsingContextState::DeleteRenderFrameProxyHost(
Sharon Yanga2fe85e2022-02-09 21:38:29196 SiteInstanceGroup* site_instance_group) {
197 site_instance_group->RemoveObserver(this);
198 proxy_hosts_.erase(site_instance_group->GetId());
Harkiran Bolariae182a5942021-12-20 17:23:31199}
200
Harkiran Bolaria5ce27632022-01-20 15:05:05201void BrowsingContextState::SendFramePolicyUpdatesToProxies(
202 SiteInstance* parent_site_instance,
203 const blink::FramePolicy& frame_policy) {
204 // Notify all of the frame's proxies about updated policies, excluding
205 // the parent process since it already knows the latest state.
206 for (const auto& pair : proxy_hosts_) {
207 if (pair.second->GetSiteInstance() != parent_site_instance) {
208 pair.second->GetAssociatedRemoteFrame()->DidUpdateFramePolicy(
209 frame_policy);
210 }
211 }
212}
213
Harkiran Bolaria2912a6b32022-02-22 16:43:45214RenderFrameProxyHost* BrowsingContextState::CreateRenderFrameProxyHost(
215 SiteInstance* site_instance,
216 const scoped_refptr<RenderViewHostImpl>& rvh,
217 FrameTreeNode* frame_tree_node) {
218 if (features::GetBrowsingContextMode() ==
219 features::BrowsingContextStateImplementationType::
220 kLegacyOneToOneWithFrameTreeNode) {
221 DCHECK_EQ(this,
222 frame_tree_node->current_frame_host()->browsing_context_state());
223 }
224
225 auto site_instance_group_id =
226 static_cast<SiteInstanceImpl*>(site_instance)->group()->GetId();
227 CHECK(proxy_hosts_.find(site_instance_group_id) == proxy_hosts_.end())
228 << "A proxy already existed for this SiteInstanceGroup.";
229 RenderFrameProxyHost* proxy_host =
230 new RenderFrameProxyHost(site_instance, std::move(rvh), frame_tree_node);
231 proxy_hosts_[site_instance_group_id] = base::WrapUnique(proxy_host);
232 static_cast<SiteInstanceImpl*>(site_instance)->group()->AddObserver(this);
233
234 TRACE_EVENT_INSTANT(
235 "navigation", "BrowsingContextState::CreateRenderFrameProxyHost",
236 perfetto::protos::pbzero::ChromeTrackEvent::kRenderFrameProxyHost,
237 *proxy_host);
238 return proxy_host;
239}
240
Harkiran Bolaria8dec6f92021-12-07 14:57:12241} // namespace content