blob: 9b373d16a0fd1a6d29ea751fe3f59f7541d4b80c [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2021 The Chromium Authors
Sreeja Kamishetty9e1d0e732021-05-27 18:20:092// 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/page_impl.h"
6
Matt Falkenhagenf78c2192021-07-24 02:01:437#include "base/barrier_closure.h"
Dominic Farolino5c606c12021-12-18 09:40:148#include "base/i18n/character_encoding.h"
Lingqi Chidcf722442021-09-02 01:47:199#include "base/trace_event/optional_trace_event.h"
Jeremy Roman4bd173d2021-06-17 00:05:4410#include "content/browser/manifest/manifest_manager_host.h"
Dave Tapuska9c9afe82021-06-22 19:07:4511#include "content/browser/renderer_host/frame_tree_node.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2612#include "content/browser/renderer_host/page_delegate.h"
Julie Jeongeun Kim9e204512021-06-24 07:28:5413#include "content/browser/renderer_host/render_frame_host_delegate.h"
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0914#include "content/browser/renderer_host/render_frame_host_impl.h"
Lingqi Chidcf722442021-09-02 01:47:1915#include "content/browser/renderer_host/render_frame_proxy_host.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2616#include "content/browser/renderer_host/render_view_host_delegate.h"
Matt Falkenhagenf78c2192021-07-24 02:01:4317#include "content/browser/renderer_host/render_view_host_impl.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2618#include "content/public/browser/render_view_host.h"
Sreeja Kamishetty0be3b1b2021-08-12 17:04:1519#include "third_party/blink/public/common/loader/loader_constants.h"
Julie Jeongeun Kim33ef6a202022-03-22 09:46:1120#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2621#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0922
23namespace content {
Jeremy Roman2d8dfe132021-07-06 20:51:2624
25PageImpl::PageImpl(RenderFrameHostImpl& rfh, PageDelegate& delegate)
Lingqi Chidcf722442021-09-02 01:47:1926 : main_document_(rfh),
27 delegate_(delegate),
28 text_autosizer_page_info_({0, 0, 1.f}) {}
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0929
Sreeja Kamishetty1b5c1432021-06-25 11:32:5930PageImpl::~PageImpl() {
31 // As SupportsUserData is a base class of PageImpl, Page members will be
32 // destroyed before running ~SupportsUserData, which would delete the
33 // associated PageUserData objects. Avoid this by calling ClearAllUserData
34 // explicitly here to ensure that the PageUserData destructors can access
35 // associated Page object.
36 ClearAllUserData();
37}
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0938
Julie Jeongeun Kim9e204512021-06-24 07:28:5439const absl::optional<GURL>& PageImpl::GetManifestUrl() const {
Sreeja Kamishetty7c91ab22021-06-03 13:29:5240 return manifest_url_;
41}
42
Jeremy Roman4bd173d2021-06-17 00:05:4443void PageImpl::GetManifest(GetManifestCallback callback) {
44 ManifestManagerHost* manifest_manager_host =
Julie Jeongeun Kim33ef6a202022-03-22 09:46:1145 ManifestManagerHost::GetOrCreateForPage(*this);
Jeremy Roman4bd173d2021-06-17 00:05:4446 manifest_manager_host->GetManifest(std::move(callback));
47}
48
Dave Tapuska9c9afe82021-06-22 19:07:4549bool PageImpl::IsPrimary() {
Dominic Farolino4bc10ee2021-08-31 00:37:3650 // TODO(1244137): Check for portals as well, once they are migrated to MPArch.
51 if (main_document_.IsFencedFrameRoot())
52 return false;
53
Dave Tapuska9c9afe82021-06-22 19:07:4554 return main_document_.lifecycle_state() ==
Khushalc5eaf222021-06-30 20:15:4855 RenderFrameHostImpl::LifecycleStateImpl::kActive;
Dave Tapuska9c9afe82021-06-22 19:07:4556}
57
Julie Jeongeun Kim9e204512021-06-24 07:28:5458void PageImpl::UpdateManifestUrl(const GURL& manifest_url) {
59 manifest_url_ = manifest_url;
60
61 // If |main_document_| is not active, the notification is sent on the page
62 // activation.
63 if (!main_document_.IsActive())
64 return;
65
66 main_document_.delegate()->OnManifestUrlChanged(*this);
67}
68
Jeremy Roman2d8dfe132021-07-06 20:51:2669void PageImpl::WriteIntoTrace(perfetto::TracedValue context) {
70 auto dict = std::move(context).WriteDictionary();
71 dict.Add("main_document", main_document_);
72}
73
Miyoung Shinfa182e472021-09-03 12:39:3274base::WeakPtr<Page> PageImpl::GetWeakPtr() {
75 return weak_factory_.GetWeakPtr();
76}
77
Yao Xiaoc7224362022-02-16 08:21:4078base::WeakPtr<PageImpl> PageImpl::GetWeakPtrImpl() {
79 return weak_factory_.GetWeakPtr();
80}
81
Kevin McNee3183a7792021-11-09 21:03:3682bool PageImpl::IsPageScaleFactorOne() {
Kevin McNeec4325ba2022-04-08 23:18:2383 return GetPageScaleFactor() == 1.f;
Kevin McNee3183a7792021-11-09 21:03:3684}
85
Jeremy Roman2d8dfe132021-07-06 20:51:2686void PageImpl::OnFirstVisuallyNonEmptyPaint() {
87 did_first_visually_non_empty_paint_ = true;
88 delegate_.OnFirstVisuallyNonEmptyPaint(*this);
89}
90
91void PageImpl::OnThemeColorChanged(const absl::optional<SkColor>& theme_color) {
92 main_document_theme_color_ = theme_color;
93 delegate_.OnThemeColorChanged(*this);
94}
95
96void PageImpl::DidChangeBackgroundColor(SkColor background_color,
97 bool color_adjust) {
98 main_document_background_color_ = background_color;
99 delegate_.OnBackgroundColorChanged(*this);
100 if (color_adjust) {
101 // <meta name="color-scheme" content="dark"> may pass the dark canvas
102 // background before the first paint in order to avoid flashing the white
103 // background in between loading documents. If we perform a navigation
104 // within the same renderer process, we keep the content background from the
105 // previous page while rendering is blocked in the new page, but for cross
106 // process navigations we would paint the default background (typically
107 // white) while the rendering is blocked.
108 main_document_.GetRenderWidgetHost()->GetView()->SetContentBackgroundColor(
109 background_color);
110 }
111}
112
Michael Bai19f17a302021-12-08 04:08:33113void PageImpl::DidInferColorScheme(
114 blink::mojom::PreferredColorScheme color_scheme) {
115 main_document_inferred_color_scheme_ = color_scheme;
116 delegate_.DidInferColorScheme(*this);
117}
118
Jeremy Roman2d8dfe132021-07-06 20:51:26119void PageImpl::SetContentsMimeType(std::string mime_type) {
120 contents_mime_type_ = std::move(mime_type);
121}
122
Lingqi Chidcf722442021-09-02 01:47:19123void PageImpl::OnTextAutosizerPageInfoChanged(
124 blink::mojom::TextAutosizerPageInfoPtr page_info) {
125 OPTIONAL_TRACE_EVENT0("content", "PageImpl::OnTextAutosizerPageInfoChanged");
126
Dave Tapuska2cf1f532022-08-10 15:30:49127 // Keep a copy of `page_info` in case we create a new `blink::WebView` before
128 // the next update, so that the PageImpl can tell the newly created
129 // `blink::WebView` about the autosizer info.
Lingqi Chidcf722442021-09-02 01:47:19130 text_autosizer_page_info_.main_frame_width = page_info->main_frame_width;
131 text_autosizer_page_info_.main_frame_layout_width =
132 page_info->main_frame_layout_width;
133 text_autosizer_page_info_.device_scale_adjustment =
134 page_info->device_scale_adjustment;
135
136 auto remote_frames_broadcast_callback = base::BindRepeating(
137 [](const blink::mojom::TextAutosizerPageInfo& page_info,
138 RenderFrameProxyHost* proxy_host) {
139 DCHECK(proxy_host);
140 proxy_host->GetAssociatedRemoteMainFrame()->UpdateTextAutosizerPageInfo(
141 page_info.Clone());
142 },
143 text_autosizer_page_info_);
144
145 main_document_.frame_tree()
146 ->root()
147 ->render_manager()
148 ->ExecuteRemoteFramesBroadcastMethod(
149 std::move(remote_frames_broadcast_callback),
150 main_document_.GetSiteInstance());
151}
152
Matt Falkenhagenf78c2192021-07-24 02:01:43153void PageImpl::SetActivationStartTime(base::TimeTicks activation_start) {
154 DCHECK(!activation_start_time_for_prerendering_);
155 activation_start_time_for_prerendering_ = activation_start;
156}
157
158void PageImpl::ActivateForPrerendering(
159 std::set<RenderViewHostImpl*>& render_view_hosts) {
160 base::OnceClosure did_activate_render_views =
161 base::BindOnce(&PageImpl::DidActivateAllRenderViewsForPrerendering,
162 weak_factory_.GetWeakPtr());
163
164 base::RepeatingClosure barrier = base::BarrierClosure(
165 render_view_hosts.size(), std::move(did_activate_render_views));
166 for (RenderViewHostImpl* rvh : render_view_hosts) {
167 base::TimeTicks navigation_start_to_send;
168 // Only send navigation_start to the RenderViewHost for the main frame to
169 // avoid sending the info cross-origin. Only this RenderViewHost needs the
170 // info, as we expect the other RenderViewHosts are made for cross-origin
171 // iframes which have not yet loaded their document. To the renderer, it
172 // just looks like an ongoing navigation is happening in the frame and has
173 // not yet committed. These RenderViews still need to know about activation
174 // so their documents are created in the non-prerendered state once their
175 // navigation is committed.
176 if (main_document_.GetRenderViewHost() == rvh)
177 navigation_start_to_send = *activation_start_time_for_prerendering_;
178
Hiroki Nakagawaab53cd22022-04-13 19:18:02179 auto params = blink::mojom::PrerenderPageActivationParams::New();
180 params->was_user_activated =
181 main_document_.frame_tree_node()->has_received_user_gesture_before_nav()
182 ? blink::mojom::WasActivatedOption::kYes
183 : blink::mojom::WasActivatedOption::kNo;
184 params->activation_start = navigation_start_to_send;
185 rvh->ActivatePrerenderedPage(std::move(params), barrier);
Matt Falkenhagenf78c2192021-07-24 02:01:43186 }
187
188 // Prepare each RenderFrameHostImpl in this Page for activation.
189 // TODO(https://crbug.com/1232528): Currently we check GetPage() below because
190 // RenderFrameHostImpls may be in a different Page, if, e.g., they are in an
191 // inner WebContents. These are in a different FrameTree which might not know
192 // it is being prerendered. We should teach these FrameTrees that they are
193 // being prerendered, or ban inner FrameTrees in a prerendering page.
Daniel Cheng982f2b22022-08-25 23:46:16194 main_document_.ForEachRenderFrameHostIncludingSpeculative(
195 [this](RenderFrameHostImpl* rfh) {
196 if (&rfh->GetPage() != this)
Matt Falkenhagenf78c2192021-07-24 02:01:43197 return;
198 rfh->RendererWillActivateForPrerendering();
Daniel Cheng982f2b22022-08-25 23:46:16199 });
Matt Falkenhagenf78c2192021-07-24 02:01:43200}
201
Sreeja Kamishetty81fbeefb2021-08-12 07:21:41202void PageImpl::MaybeDispatchLoadEventsOnPrerenderActivation() {
203 DCHECK(IsPrimary());
204
Sreeja Kamishetty0be3b1b2021-08-12 17:04:15205 // Dispatch LoadProgressChanged notification on activation with the
206 // prerender last load progress value if the value is not equal to
207 // blink::kFinalLoadProgress, whose notification is dispatched during call
208 // to DidStopLoading.
209 if (load_progress() != blink::kFinalLoadProgress)
210 main_document_.DidChangeLoadProgress(load_progress());
211
Sreeja Kamishetty49783302022-01-28 17:52:25212 // Dispatch PrimaryMainDocumentElementAvailable before dispatching following
213 // load complete events.
214 if (is_main_document_element_available())
215 main_document_.MainDocumentElementAvailable(uses_temporary_zoom_level());
Sreeja Kamishettycd5560912021-11-22 11:54:53216
Sreeja Kamishetty81fbeefb2021-08-12 07:21:41217 main_document_.ForEachRenderFrameHost(
Daniel Cheng982f2b22022-08-25 23:46:16218 &RenderFrameHostImpl::MaybeDispatchDOMContentLoadedOnPrerenderActivation);
Sreeja Kamishetty81fbeefb2021-08-12 07:21:41219
220 if (is_on_load_completed_in_main_document())
221 main_document_.DocumentOnLoadCompleted();
222
223 main_document_.ForEachRenderFrameHost(
Daniel Cheng982f2b22022-08-25 23:46:16224 &RenderFrameHostImpl::MaybeDispatchDidFinishLoadOnPrerenderActivation);
Sreeja Kamishetty81fbeefb2021-08-12 07:21:41225}
226
Matt Falkenhagenf78c2192021-07-24 02:01:43227void PageImpl::DidActivateAllRenderViewsForPrerendering() {
228 // Tell each RenderFrameHostImpl in this Page that activation finished.
Daniel Cheng982f2b22022-08-25 23:46:16229 main_document_.ForEachRenderFrameHost([this](RenderFrameHostImpl* rfh) {
230 if (&rfh->GetPage() != this)
231 return;
232 rfh->RendererDidActivateForPrerendering();
233 });
Matt Falkenhagenf78c2192021-07-24 02:01:43234}
235
Sreeja Kamishetty1b5c1432021-06-25 11:32:59236RenderFrameHost& PageImpl::GetMainDocumentHelper() {
237 return main_document_;
238}
239
240RenderFrameHostImpl& PageImpl::GetMainDocument() const {
241 return main_document_;
242}
243
Yoshisato Yanagisawad016d62d32021-10-15 04:38:55244void PageImpl::UpdateBrowserControlsState(cc::BrowserControlsState constraints,
245 cc::BrowserControlsState current,
246 bool animate) {
247 // TODO(https://crbug.com/1154852): Asking for the LocalMainFrame interface
248 // before the RenderFrame is created is racy.
Nasko Oskov8b04f402022-05-26 23:29:56249 if (!GetMainDocument().IsRenderFrameLive())
Yoshisato Yanagisawad016d62d32021-10-15 04:38:55250 return;
251
252 GetMainDocument().GetAssociatedLocalMainFrame()->UpdateBrowserControlsState(
253 constraints, current, animate);
254}
255
Kevin McNeec4325ba2022-04-08 23:18:23256float PageImpl::GetPageScaleFactor() const {
257 return GetMainDocument().GetPageScaleFactor();
258}
259
Dominic Farolino5c606c12021-12-18 09:40:14260void PageImpl::UpdateEncoding(const std::string& encoding_name) {
261 if (encoding_name == last_reported_encoding_)
262 return;
263 last_reported_encoding_ = encoding_name;
264
265 canonical_encoding_ =
266 base::GetCanonicalEncodingNameByAliasName(encoding_name);
267}
268
Yoshisato Yanagisawa8ae0d112022-04-20 01:49:30269void PageImpl::NotifyVirtualKeyboardOverlayRect(
270 const gfx::Rect& keyboard_rect) {
271 // TODO(https://crbug.com/1317002): send notification to outer frames if
272 // needed.
273 DCHECK(virtual_keyboard_overlays_content());
274 GetMainDocument().GetAssociatedLocalFrame()->NotifyVirtualKeyboardOverlayRect(
275 keyboard_rect);
276}
277
Yoshisato Yanagisawa668f8442022-04-20 04:45:58278base::flat_map<std::string, std::string> PageImpl::GetKeyboardLayoutMap() {
279 return GetMainDocument().GetRenderWidgetHost()->GetKeyboardLayoutMap();
280}
281
Sreeja Kamishetty9e1d0e732021-05-27 18:20:09282} // namespace content