blob: 8e1bb7e5ba47b42b3562ba9b5111d00da9ef6e04 [file] [log] [blame]
Sreeja Kamishetty9e1d0e732021-05-27 18:20:091// Copyright 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/page_impl.h"
6
Matt Falkenhagenf78c2192021-07-24 02:01:437#include "base/barrier_closure.h"
Jeremy Roman4bd173d2021-06-17 00:05:448#include "content/browser/manifest/manifest_manager_host.h"
Dave Tapuska9c9afe82021-06-22 19:07:459#include "content/browser/renderer_host/frame_tree_node.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2610#include "content/browser/renderer_host/page_delegate.h"
Julie Jeongeun Kim9e204512021-06-24 07:28:5411#include "content/browser/renderer_host/render_frame_host_delegate.h"
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0912#include "content/browser/renderer_host/render_frame_host_impl.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2613#include "content/browser/renderer_host/render_view_host_delegate.h"
Matt Falkenhagenf78c2192021-07-24 02:01:4314#include "content/browser/renderer_host/render_view_host_impl.h"
Jeremy Roman2d8dfe132021-07-06 20:51:2615#include "content/public/browser/render_view_host.h"
16#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0917
18namespace content {
Jeremy Roman2d8dfe132021-07-06 20:51:2619
20PageImpl::PageImpl(RenderFrameHostImpl& rfh, PageDelegate& delegate)
21 : main_document_(rfh), delegate_(delegate) {}
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0922
Sreeja Kamishetty1b5c1432021-06-25 11:32:5923PageImpl::~PageImpl() {
24 // As SupportsUserData is a base class of PageImpl, Page members will be
25 // destroyed before running ~SupportsUserData, which would delete the
26 // associated PageUserData objects. Avoid this by calling ClearAllUserData
27 // explicitly here to ensure that the PageUserData destructors can access
28 // associated Page object.
29 ClearAllUserData();
30}
Sreeja Kamishetty9e1d0e732021-05-27 18:20:0931
Julie Jeongeun Kim9e204512021-06-24 07:28:5432const absl::optional<GURL>& PageImpl::GetManifestUrl() const {
Sreeja Kamishetty7c91ab22021-06-03 13:29:5233 return manifest_url_;
34}
35
Jeremy Roman4bd173d2021-06-17 00:05:4436void PageImpl::GetManifest(GetManifestCallback callback) {
37 ManifestManagerHost* manifest_manager_host =
38 ManifestManagerHost::GetOrCreateForCurrentDocument(&main_document_);
39 manifest_manager_host->GetManifest(std::move(callback));
40}
41
Dave Tapuska9c9afe82021-06-22 19:07:4542bool PageImpl::IsPrimary() {
43 // TODO(https://crbug.com/1222722): Query RenderFrameHost::IsInFencedFrame()
44 // when it is available.
45 return main_document_.lifecycle_state() ==
Khushalc5eaf222021-06-30 20:15:4846 RenderFrameHostImpl::LifecycleStateImpl::kActive;
Dave Tapuska9c9afe82021-06-22 19:07:4547}
48
Julie Jeongeun Kim9e204512021-06-24 07:28:5449void PageImpl::UpdateManifestUrl(const GURL& manifest_url) {
50 manifest_url_ = manifest_url;
51
52 // If |main_document_| is not active, the notification is sent on the page
53 // activation.
54 if (!main_document_.IsActive())
55 return;
56
57 main_document_.delegate()->OnManifestUrlChanged(*this);
58}
59
Jeremy Roman2d8dfe132021-07-06 20:51:2660void PageImpl::WriteIntoTrace(perfetto::TracedValue context) {
61 auto dict = std::move(context).WriteDictionary();
62 dict.Add("main_document", main_document_);
63}
64
65void PageImpl::OnFirstVisuallyNonEmptyPaint() {
66 did_first_visually_non_empty_paint_ = true;
67 delegate_.OnFirstVisuallyNonEmptyPaint(*this);
68}
69
70void PageImpl::OnThemeColorChanged(const absl::optional<SkColor>& theme_color) {
71 main_document_theme_color_ = theme_color;
72 delegate_.OnThemeColorChanged(*this);
73}
74
75void PageImpl::DidChangeBackgroundColor(SkColor background_color,
76 bool color_adjust) {
77 main_document_background_color_ = background_color;
78 delegate_.OnBackgroundColorChanged(*this);
79 if (color_adjust) {
80 // <meta name="color-scheme" content="dark"> may pass the dark canvas
81 // background before the first paint in order to avoid flashing the white
82 // background in between loading documents. If we perform a navigation
83 // within the same renderer process, we keep the content background from the
84 // previous page while rendering is blocked in the new page, but for cross
85 // process navigations we would paint the default background (typically
86 // white) while the rendering is blocked.
87 main_document_.GetRenderWidgetHost()->GetView()->SetContentBackgroundColor(
88 background_color);
89 }
90}
91
92void PageImpl::SetContentsMimeType(std::string mime_type) {
93 contents_mime_type_ = std::move(mime_type);
94}
95
Matt Falkenhagenf78c2192021-07-24 02:01:4396void PageImpl::SetActivationStartTime(base::TimeTicks activation_start) {
97 DCHECK(!activation_start_time_for_prerendering_);
98 activation_start_time_for_prerendering_ = activation_start;
99}
100
101void PageImpl::ActivateForPrerendering(
102 std::set<RenderViewHostImpl*>& render_view_hosts) {
103 base::OnceClosure did_activate_render_views =
104 base::BindOnce(&PageImpl::DidActivateAllRenderViewsForPrerendering,
105 weak_factory_.GetWeakPtr());
106
107 base::RepeatingClosure barrier = base::BarrierClosure(
108 render_view_hosts.size(), std::move(did_activate_render_views));
109 for (RenderViewHostImpl* rvh : render_view_hosts) {
110 base::TimeTicks navigation_start_to_send;
111 // Only send navigation_start to the RenderViewHost for the main frame to
112 // avoid sending the info cross-origin. Only this RenderViewHost needs the
113 // info, as we expect the other RenderViewHosts are made for cross-origin
114 // iframes which have not yet loaded their document. To the renderer, it
115 // just looks like an ongoing navigation is happening in the frame and has
116 // not yet committed. These RenderViews still need to know about activation
117 // so their documents are created in the non-prerendered state once their
118 // navigation is committed.
119 if (main_document_.GetRenderViewHost() == rvh)
120 navigation_start_to_send = *activation_start_time_for_prerendering_;
121
122 rvh->ActivatePrerenderedPage(navigation_start_to_send, barrier);
123 }
124
125 // Prepare each RenderFrameHostImpl in this Page for activation.
126 // TODO(https://crbug.com/1232528): Currently we check GetPage() below because
127 // RenderFrameHostImpls may be in a different Page, if, e.g., they are in an
128 // inner WebContents. These are in a different FrameTree which might not know
129 // it is being prerendered. We should teach these FrameTrees that they are
130 // being prerendered, or ban inner FrameTrees in a prerendering page.
131 main_document_.ForEachRenderFrameHost(base::BindRepeating(
132 [](PageImpl* page, RenderFrameHostImpl* rfh) {
133 if (&rfh->GetPage() != page)
134 return;
135 rfh->RendererWillActivateForPrerendering();
136 },
137 this));
138}
139
140void PageImpl::DidActivateAllRenderViewsForPrerendering() {
141 // Tell each RenderFrameHostImpl in this Page that activation finished.
142 main_document_.ForEachRenderFrameHost(base::BindRepeating(
143 [](PageImpl* page, RenderFrameHostImpl* rfh) {
144 if (&rfh->GetPage() != page)
145 return;
146 rfh->RendererDidActivateForPrerendering();
147 },
148 this));
149}
150
Sreeja Kamishetty1b5c1432021-06-25 11:32:59151RenderFrameHost& PageImpl::GetMainDocumentHelper() {
152 return main_document_;
153}
154
155RenderFrameHostImpl& PageImpl::GetMainDocument() const {
156 return main_document_;
157}
158
Sreeja Kamishetty9e1d0e732021-05-27 18:20:09159} // namespace content