Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2021 The Chromium Authors |
Harkiran Bolaria | 8dec6f9 | 2021-12-07 14:57:12 | [diff] [blame] | 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 | |
David Sanders | 27d3205 | 2022-04-04 18:08:19 | [diff] [blame] | 7 | #include "base/memory/ptr_util.h" |
Harkiran Bolaria | 2912a6b3 | 2022-02-22 16:43:45 | [diff] [blame] | 8 | #include "content/browser/renderer_host/frame_tree_node.h" |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 9 | #include "content/browser/renderer_host/render_frame_host_impl.h" |
Harkiran Bolaria | 2912a6b3 | 2022-02-22 16:43:45 | [diff] [blame] | 10 | #include "content/browser/renderer_host/render_view_host_impl.h" |
Charlie Reis | 37be268 | 2023-01-10 17:04:47 | [diff] [blame] | 11 | #include "content/browser/site_instance_impl.h" |
Harkiran Bolaria | 2912a6b3 | 2022-02-22 16:43:45 | [diff] [blame] | 12 | #include "content/common/content_navigation_policy.h" |
Sandor Major | 878f835 | 2025-02-18 20:16:02 | [diff] [blame] | 13 | #include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h" |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 14 | #include "services/network/public/cpp/web_sandbox_flags.h" |
| 15 | #include "services/network/public/mojom/web_sandbox_flags.mojom.h" |
| 16 | |
Harkiran Bolaria | 8dec6f9 | 2021-12-07 14:57:12 | [diff] [blame] | 17 | namespace features { |
Daniel Cheng | 0abd9f3 | 2022-09-22 04:20:11 | [diff] [blame] | 18 | BASE_FEATURE(kNewBrowsingContextStateOnBrowsingContextGroupSwap, |
| 19 | "NewBrowsingContextStateOnBrowsingContextGroupSwap", |
| 20 | base::FEATURE_DISABLED_BY_DEFAULT); |
Harkiran Bolaria | 8dec6f9 | 2021-12-07 14:57:12 | [diff] [blame] | 21 | |
| 22 | BrowsingContextStateImplementationType 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 | |
| 34 | namespace content { |
| 35 | |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 36 | using perfetto::protos::pbzero::ChromeTrackEvent; |
| 37 | |
Harkiran Bolaria | 4eacb3a | 2021-12-13 20:03:47 | [diff] [blame] | 38 | BrowsingContextState::BrowsingContextState( |
Harkiran Bolaria | 880a763 | 2022-02-28 16:02:50 | [diff] [blame] | 39 | blink::mojom::FrameReplicationStatePtr replication_state, |
Arthur Sonzogni | 91fd79b | 2023-04-19 15:37:14 | [diff] [blame] | 40 | RenderFrameHostImpl* parent, |
Camille Lamy | c935192 | 2025-05-01 02:57:44 | [diff] [blame] | 41 | std::optional<BrowsingInstanceId> browsing_instance_id) |
Harkiran Bolaria | 0b3bdef0 | 2022-03-10 13:04:40 | [diff] [blame] | 42 | : replication_state_(std::move(replication_state)), |
| 43 | parent_(parent), |
Camille Lamy | c935192 | 2025-05-01 02:57:44 | [diff] [blame] | 44 | browsing_instance_id_(browsing_instance_id) { |
Patrick Monette | 3250ac4 | 2025-05-09 21:55:01 | [diff] [blame] | 45 | TRACE_EVENT_BEGIN("navigation.debug", "BrowsingContextState", |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 46 | perfetto::Track::FromPointer(this), |
| 47 | "browsing_context_state_when_created", this); |
| 48 | } |
Harkiran Bolaria | 8dec6f9 | 2021-12-07 14:57:12 | [diff] [blame] | 49 | |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 50 | BrowsingContextState::~BrowsingContextState() { |
Patrick Monette | 3250ac4 | 2025-05-09 21:55:01 | [diff] [blame] | 51 | TRACE_EVENT_END("navigation.debug", perfetto::Track::FromPointer(this)); |
W. James MacLean | 0fbe7dc5 | 2023-08-22 20:20:48 | [diff] [blame] | 52 | CHECK(proxy_hosts_.empty()); |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 53 | } |
Harkiran Bolaria | 4eacb3a | 2021-12-13 20:03:47 | [diff] [blame] | 54 | |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 55 | RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHost( |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 56 | SiteInstanceGroup* site_instance_group, |
| 57 | ProxyAccessMode proxy_access_mode) const { |
Peilin Wang | 9791d80 | 2023-05-09 19:07:31 | [diff] [blame] | 58 | TRACE_EVENT_BEGIN("navigation.debug", |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 59 | "BrowsingContextState::GetRenderFrameProxyHost", |
| 60 | ChromeTrackEvent::kBrowsingContextState, this, |
| 61 | ChromeTrackEvent::kSiteInstanceGroup, site_instance_group); |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 62 | auto* proxy = |
| 63 | GetRenderFrameProxyHostImpl(site_instance_group, proxy_access_mode); |
Peilin Wang | 9791d80 | 2023-05-09 19:07:31 | [diff] [blame] | 64 | TRACE_EVENT_END("navigation.debug", ChromeTrackEvent::kRenderFrameProxyHost, |
| 65 | proxy); |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 66 | return proxy; |
| 67 | } |
| 68 | |
| 69 | RenderFrameProxyHost* BrowsingContextState::GetRenderFrameProxyHostImpl( |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 70 | SiteInstanceGroup* site_instance_group, |
| 71 | ProxyAccessMode proxy_access_mode) const { |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 72 | if (features::GetBrowsingContextMode() == |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 73 | features::BrowsingContextStateImplementationType:: |
| 74 | kSwapForCrossBrowsingInstanceNavigations && |
| 75 | proxy_access_mode == ProxyAccessMode::kRegular) { |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 76 | // 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 Lamy | c935192 | 2025-05-01 02:57:44 | [diff] [blame] | 79 | // BrowsingInstance, the browsing_instance_id of the BrowsingContextState |
Arthur Hemery | 08d8288 | 2023-04-27 12:33:14 | [diff] [blame] | 80 | // (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 Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 86 | // |
Arthur Hemery | 08d8288 | 2023-04-27 12:33:14 | [diff] [blame] | 87 | // 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 Lamy | c935192 | 2025-05-01 02:57:44 | [diff] [blame] | 90 | CHECK_EQ(browsing_instance_id_.value(), |
| 91 | site_instance_group->browsing_instance_id()); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 92 | } |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 93 | auto it = proxy_hosts_.find(site_instance_group->GetId()); |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 94 | if (it != proxy_hosts_.end()) { |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 95 | return it->second.get(); |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 96 | } |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 97 | return nullptr; |
| 98 | } |
| 99 | |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 100 | void BrowsingContextState::DeleteRenderFrameProxyHost( |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 101 | SiteInstanceGroup* site_instance_group, |
| 102 | ProxyAccessMode proxy_access_mode) { |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 103 | if (features::GetBrowsingContextMode() == |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 104 | features::BrowsingContextStateImplementationType:: |
| 105 | kSwapForCrossBrowsingInstanceNavigations && |
| 106 | proxy_access_mode == ProxyAccessMode::kRegular) { |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 107 | // See comments in GetRenderFrameProxyHost for why this check is needed. |
Camille Lamy | c935192 | 2025-05-01 02:57:44 | [diff] [blame] | 108 | CHECK_EQ(browsing_instance_id_.value(), |
| 109 | site_instance_group->browsing_instance_id()); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 110 | } |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 111 | TRACE_EVENT("navigation", "BrowsingContextState::DeleteRenderFrameProxyHost", |
| 112 | ChromeTrackEvent::kBrowsingContextState, this, |
| 113 | ChromeTrackEvent::kSiteInstanceGroup, site_instance_group); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 114 | site_instance_group->RemoveObserver(this); |
| 115 | proxy_hosts_.erase(site_instance_group->GetId()); |
| 116 | } |
| 117 | |
| 118 | RenderFrameProxyHost* BrowsingContextState::CreateRenderFrameProxyHost( |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 119 | SiteInstanceGroup* site_instance_group, |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 120 | const scoped_refptr<RenderViewHostImpl>& rvh, |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 121 | FrameTreeNode* frame_tree_node, |
Dave Tapuska | 14457010 | 2022-08-02 19:28:27 | [diff] [blame] | 122 | ProxyAccessMode proxy_access_mode, |
| 123 | const blink::RemoteFrameToken& frame_token) { |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 124 | TRACE_EVENT_BEGIN( |
| 125 | "navigation", "BrowsingContextState::CreateRenderFrameProxyHost", |
| 126 | ChromeTrackEvent::kBrowsingContextState, this, |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 127 | ChromeTrackEvent::kSiteInstanceGroup, site_instance_group, |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 128 | ChromeTrackEvent::kRenderViewHost, rvh ? rvh.get() : nullptr, |
| 129 | ChromeTrackEvent::kFrameTreeNodeInfo, frame_tree_node); |
| 130 | |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 131 | 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 Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 139 | features::BrowsingContextStateImplementationType:: |
| 140 | kSwapForCrossBrowsingInstanceNavigations && |
| 141 | proxy_access_mode == ProxyAccessMode::kRegular) { |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 142 | // See comments in GetRenderFrameProxyHost for why this check is needed. |
Camille Lamy | c935192 | 2025-05-01 02:57:44 | [diff] [blame] | 143 | CHECK_EQ(browsing_instance_id_.value(), |
| 144 | site_instance_group->browsing_instance_id()); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 145 | } |
| 146 | |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 147 | auto site_instance_group_id = site_instance_group->GetId(); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 148 | CHECK(proxy_hosts_.find(site_instance_group_id) == proxy_hosts_.end()) |
| 149 | << "A proxy already existed for this SiteInstanceGroup."; |
Dave Tapuska | 14457010 | 2022-08-02 19:28:27 | [diff] [blame] | 150 | RenderFrameProxyHost* proxy_host = new RenderFrameProxyHost( |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 151 | site_instance_group, std::move(rvh), frame_tree_node, frame_token); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 152 | proxy_hosts_[site_instance_group_id] = base::WrapUnique(proxy_host); |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 153 | site_instance_group->AddObserver(this); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 154 | |
Harkiran Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 155 | TRACE_EVENT_END("navigation", ChromeTrackEvent::kRenderFrameProxyHost, |
| 156 | proxy_host); |
Harkiran Bolaria | 5c5a9739 | 2022-03-10 14:18:50 | [diff] [blame] | 157 | return proxy_host; |
| 158 | } |
| 159 | |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 160 | RenderFrameProxyHost* BrowsingContextState::CreateOuterDelegateProxy( |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 161 | SiteInstanceGroup* outer_contents_site_instance_group, |
Dave Tapuska | 14457010 | 2022-08-02 19:28:27 | [diff] [blame] | 162 | FrameTreeNode* frame_tree_node, |
| 163 | const blink::RemoteFrameToken& frame_token) { |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 164 | // We only get here when Delegate for this manager is an inner delegate. |
Sharon Yang | dcc5f25 | 2024-05-09 18:27:23 | [diff] [blame] | 165 | return CreateRenderFrameProxyHost(outer_contents_site_instance_group, |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 166 | /*rvh=*/nullptr, frame_tree_node, |
Dave Tapuska | 14457010 | 2022-08-02 19:28:27 | [diff] [blame] | 167 | ProxyAccessMode::kAllowOuterDelegate, |
| 168 | frame_token); |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 169 | } |
| 170 | |
Harkiran Bolaria | d22a1dca | 2022-02-22 17:01:12 | [diff] [blame] | 171 | size_t BrowsingContextState::GetProxyCount() { |
| 172 | return proxy_hosts_.size(); |
| 173 | } |
| 174 | |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 175 | bool BrowsingContextState::UpdateFramePolicyHeaders( |
| 176 | network::mojom::WebSandboxFlags sandbox_flags, |
Sandor Major | 878f835 | 2025-02-18 20:16:02 | [diff] [blame] | 177 | const network::ParsedPermissionsPolicy& parsed_header) { |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 178 | 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 Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 193 | TRACE_EVENT("navigation", |
| 194 | "BrowsingContextState::UpdateFramePolicyHeaders broadcast"); |
Dave Tapuska | 82b5401 | 2022-07-15 23:26:10 | [diff] [blame] | 195 | ExecuteRemoteFramesBroadcastMethod( |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 196 | [this](RenderFrameProxyHost* proxy) { |
| 197 | proxy->GetAssociatedRemoteFrame()->DidSetFramePolicyHeaders( |
| 198 | replication_state_->active_sandbox_flags, |
| 199 | replication_state_->permissions_policy_header); |
| 200 | }, |
Sharon Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 201 | /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr); |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 202 | } |
| 203 | return changed; |
| 204 | } |
| 205 | |
| 206 | bool 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 Gale | 81f4f2c7 | 2024-04-22 19:33:31 | [diff] [blame] | 211 | // TODO(crbug.com/40202483). Enforce the invariant mentioned above, |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 212 | // 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 Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 222 | |
Harkiran Bolaria | 4eacb3a | 2021-12-13 20:03:47 | [diff] [blame] | 223 | 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 Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 235 | |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 236 | 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 Bolaria | 7fdb4c64 | 2021-12-20 12:47:00 | [diff] [blame] | 240 | } |
| 241 | |
Harkiran Bolaria | 880a763 | 2022-02-28 16:02:50 | [diff] [blame] | 242 | void 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 Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 260 | { |
| 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 Bolaria | 880a763 | 2022-02-28 16:02:50 | [diff] [blame] | 270 | replication_state_->unique_name = unique_name; |
| 271 | replication_state_->name = name; |
| 272 | } |
| 273 | |
Harkiran Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 274 | void 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 Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 283 | { |
| 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 Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 295 | |
| 296 | replication_state_->origin = origin; |
| 297 | replication_state_->has_potentially_trustworthy_unique_origin = |
| 298 | is_potentially_trustworthy_unique_origin; |
| 299 | } |
| 300 | |
| 301 | void BrowsingContextState::SetInsecureRequestPolicy( |
| 302 | blink::mojom::InsecureRequestPolicy policy) { |
| 303 | if (policy == replication_state_->insecure_request_policy) |
| 304 | return; |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 305 | { |
| 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 Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 315 | replication_state_->insecure_request_policy = policy; |
| 316 | } |
| 317 | |
| 318 | void 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 Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 324 | { |
| 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 Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 334 | replication_state_->insecure_navigations_set = insecure_navigations_set; |
| 335 | } |
| 336 | |
| 337 | void BrowsingContextState::OnSetHadStickyUserActivationBeforeNavigation( |
| 338 | bool value) { |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 339 | { |
| 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 Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 351 | replication_state_->has_received_user_gesture_before_nav = value; |
| 352 | } |
| 353 | |
David Bokan | fa230cc | 2022-07-22 18:02:33 | [diff] [blame] | 354 | void BrowsingContextState::SetIsAdFrame(bool is_ad_frame) { |
| 355 | if (is_ad_frame == replication_state_->is_ad_frame) |
Harkiran Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 356 | return; |
| 357 | |
David Bokan | fa230cc | 2022-07-22 18:02:33 | [diff] [blame] | 358 | replication_state_->is_ad_frame = is_ad_frame; |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 359 | { |
| 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 Bolaria | e352143 | 2021-12-14 11:27:43 | [diff] [blame] | 369 | } |
| 370 | |
Harkiran Bolaria | e182a594 | 2021-12-20 17:23:31 | [diff] [blame] | 371 | void BrowsingContextState::ActiveFrameCountIsZero( |
Sharon Yang | a2fe85e | 2022-02-09 21:38:29 | [diff] [blame] | 372 | SiteInstanceGroup* site_instance_group) { |
Sharon Yang | 417a5df | 2024-04-23 17:57:15 | [diff] [blame] | 373 | CheckIfSiteInstanceGroupIsUnused(site_instance_group, kActiveFrameCount); |
| 374 | } |
| 375 | |
| 376 | void BrowsingContextState::KeepAliveCountIsZero( |
| 377 | SiteInstanceGroup* site_instance_group) { |
| 378 | CheckIfSiteInstanceGroupIsUnused(site_instance_group, kKeepAliveCount); |
| 379 | } |
| 380 | |
| 381 | void 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 Yang | a2fe85e | 2022-02-09 21:38:29 | [diff] [blame] | 393 | RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance_group); |
Harkiran Bolaria | e182a594 | 2021-12-20 17:23:31 | [diff] [blame] | 394 | CHECK(proxy); |
| 395 | |
Sharon Yang | 417a5df | 2024-04-23 17:57:15 | [diff] [blame] | 396 | 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 Bolaria | a834778 | 2022-04-06 09:25:11 | [diff] [blame] | 407 | |
Sharon Yang | a2fe85e | 2022-02-09 21:38:29 | [diff] [blame] | 408 | DeleteRenderFrameProxyHost(site_instance_group); |
Harkiran Bolaria | e182a594 | 2021-12-20 17:23:31 | [diff] [blame] | 409 | } |
| 410 | |
| 411 | void BrowsingContextState::RenderProcessGone( |
Sharon Yang | a2fe85e | 2022-02-09 21:38:29 | [diff] [blame] | 412 | SiteInstanceGroup* site_instance_group, |
Harkiran Bolaria | e182a594 | 2021-12-20 17:23:31 | [diff] [blame] | 413 | const ChildProcessTerminationInfo& info) { |
Harkiran Bolaria | e45272d | 2022-04-12 08:05:01 | [diff] [blame] | 414 | GetRenderFrameProxyHost(site_instance_group, |
| 415 | ProxyAccessMode::kAllowOuterDelegate) |
Sharon Yang | a2fe85e | 2022-02-09 21:38:29 | [diff] [blame] | 416 | ->SetRenderFrameProxyCreated(false); |
Harkiran Bolaria | e182a594 | 2021-12-20 17:23:31 | [diff] [blame] | 417 | } |
| 418 | |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 419 | void BrowsingContextState::SendFramePolicyUpdatesToProxies( |
Sharon Yang | 571baee | 2022-03-18 19:01:54 | [diff] [blame] | 420 | SiteInstanceGroup* parent_group, |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 421 | 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 Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 424 | TRACE_EVENT( |
| 425 | "navigation", |
| 426 | "BrowsingContextState::SendFramePolicyUpdatesToProxies broadcast"); |
Dave Tapuska | 82b5401 | 2022-07-15 23:26:10 | [diff] [blame] | 427 | ExecuteRemoteFramesBroadcastMethod( |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 428 | [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 Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 434 | /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr); |
Harkiran Bolaria | 5ce2763 | 2022-01-20 15:05:05 | [diff] [blame] | 435 | } |
| 436 | |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 437 | void BrowsingContextState::OnDidStartLoading() { |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 438 | TRACE_EVENT("navigation", |
| 439 | "BrowsingContextState::OnDidStartLoading broadcast"); |
Dave Tapuska | 82b5401 | 2022-07-15 23:26:10 | [diff] [blame] | 440 | ExecuteRemoteFramesBroadcastMethod( |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 441 | [](RenderFrameProxyHost* proxy) { |
Dave Tapuska | 82b5401 | 2022-07-15 23:26:10 | [diff] [blame] | 442 | proxy->GetAssociatedRemoteFrame()->DidStartLoading(); |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 443 | }, |
Sharon Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 444 | /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr); |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 445 | } |
| 446 | |
| 447 | void BrowsingContextState::OnDidStopLoading() { |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 448 | TRACE_EVENT("navigation", "BrowsingContextState::OnDidStopLoading broadcast"); |
Dave Tapuska | 82b5401 | 2022-07-15 23:26:10 | [diff] [blame] | 449 | ExecuteRemoteFramesBroadcastMethod( |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 450 | [](RenderFrameProxyHost* proxy) { |
Dave Tapuska | 82b5401 | 2022-07-15 23:26:10 | [diff] [blame] | 451 | proxy->GetAssociatedRemoteFrame()->DidStopLoading(); |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 452 | }, |
Sharon Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 453 | /*group_to_skip=*/nullptr, /*outer_delegate_proxy=*/nullptr); |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 454 | } |
| 455 | |
Harkiran Bolaria | 0b3bdef0 | 2022-03-10 13:04:40 | [diff] [blame] | 456 | void 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 Yang | 571baee | 2022-03-18 19:01:54 | [diff] [blame] | 463 | void BrowsingContextState::UpdateOpener( |
| 464 | SiteInstanceGroup* source_site_instance_group) { |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 465 | for (const auto& pair : proxy_hosts_) { |
Sharon Yang | 571baee | 2022-03-18 19:01:54 | [diff] [blame] | 466 | if (pair.second->site_instance_group() == source_site_instance_group) |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 467 | continue; |
| 468 | pair.second->UpdateOpener(); |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | void 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 McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 480 | SiteInstanceGroup* parent_group = parent_->GetSiteInstance()->group(); |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 481 | { |
| 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 Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 495 | } |
| 496 | |
| 497 | void BrowsingContextState::ExecuteRemoteFramesBroadcastMethod( |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 498 | base::FunctionRef<void(RenderFrameProxyHost*)> callback, |
Sharon Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 499 | SiteInstanceGroup* group_to_skip, |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 500 | RenderFrameProxyHost* outer_delegate_proxy) { |
Charlie Reis | 0650ad0d | 2024-12-06 18:12:35 | [diff] [blame] | 501 | TRACE_EVENT("navigation", |
| 502 | "BrowsingContextState::ExecuteRemoteFramesBroadcastMethod"); |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 503 | for (const auto& pair : proxy_hosts_) { |
| 504 | if (outer_delegate_proxy == pair.second.get()) |
| 505 | continue; |
Sharon Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 506 | if (pair.second->site_instance_group() == group_to_skip) { |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 507 | continue; |
Sharon Yang | 6b531343 | 2023-03-24 05:07:57 | [diff] [blame] | 508 | } |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 509 | if (!pair.second->is_render_frame_proxy_live()) |
| 510 | continue; |
Kevin McNee | 7705fe8 | 2024-11-07 18:56:31 | [diff] [blame] | 511 | callback(pair.second.get()); |
Harkiran Bolaria | 3f83fba7 | 2022-03-10 17:48:40 | [diff] [blame] | 512 | } |
| 513 | } |
| 514 | |
Harkiran Bolaria | 3bf5457f | 2022-03-10 20:04:37 | [diff] [blame] | 515 | void BrowsingContextState::WriteIntoTrace( |
Alexander Timin | 074cd18 | 2022-03-23 18:11:22 | [diff] [blame] | 516 | perfetto::TracedProto<TraceProto> proto) const { |
Arthur Hemery | 08d8288 | 2023-04-27 12:33:14 | [diff] [blame] | 517 | if (browsing_instance_id_.has_value()) { |
Harkiran Bolaria | 3bf5457f | 2022-03-10 20:04:37 | [diff] [blame] | 518 | proto->set_browsing_instance_id(browsing_instance_id_.value().value()); |
Arthur Hemery | 08d8288 | 2023-04-27 12:33:14 | [diff] [blame] | 519 | } |
| 520 | |
Alexander Timin | 074cd18 | 2022-03-23 18:11:22 | [diff] [blame] | 521 | perfetto::TracedDictionary dict = std::move(proto).AddDebugAnnotations(); |
| 522 | dict.Add("this", static_cast<const void*>(this)); |
Harkiran Bolaria | 3bf5457f | 2022-03-10 20:04:37 | [diff] [blame] | 523 | } |
| 524 | |
Harkiran Bolaria | 875d4f6 | 2022-05-17 16:18:23 | [diff] [blame] | 525 | base::SafeRef<BrowsingContextState> BrowsingContextState::GetSafeRef() { |
| 526 | return weak_factory_.GetSafeRef(); |
| 527 | } |
| 528 | |
Alexander Timin | 07cad076 | 2022-03-15 00:33:17 | [diff] [blame] | 529 | } // namespace content |