blob: 208ffdf958457c9c1acab380c0b2c815e26f26c2 [file] [log] [blame]
[email protected]ce2fcd9202012-01-06 18:42:501// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]33f74972010-12-08 16:40:362// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/prerender/prerender_contents.h"
6
avib896c712015-12-26 02:10:437#include <stddef.h>
8
[email protected]48055042012-07-14 21:12:119#include <functional>
[email protected]b99b13b2011-05-04 20:59:0410#include <utility>
[email protected]c49147c32011-04-26 18:42:0411
[email protected]48ed2612014-01-21 00:30:5712#include "base/bind.h"
tripta.g3e097a92017-06-22 07:56:2613#include "base/stl_util.h"
[email protected]e309f312013-06-07 21:50:0814#include "base/strings/utf_string_conversions.h"
Eric Seckler8652dcd52018-09-20 10:42:2815#include "base/task/post_task.h"
avib896c712015-12-26 02:10:4316#include "build/build_config.h"
[email protected]25ff0862013-07-12 00:59:0317#include "chrome/browser/chrome_notification_types.h"
[email protected]02b9b2b6f2011-05-24 17:27:5018#include "chrome/browser/history/history_tab_helper.h"
[email protected]db6c4ea2013-06-14 17:53:0119#include "chrome/browser/prerender/prerender_field_trial.h"
[email protected]4c154ff82011-02-15 11:23:5920#include "chrome/browser/prerender/prerender_final_status.h"
[email protected]48055042012-07-14 21:12:1121#include "chrome/browser/prerender/prerender_handle.h"
[email protected]33f74972010-12-08 16:40:3622#include "chrome/browser/prerender/prerender_manager.h"
[email protected]a303db72014-01-06 05:08:1923#include "chrome/browser/prerender/prerender_manager_factory.h"
John Abd-El-Malekd2377982018-01-08 22:23:1224#include "chrome/browser/prerender/prerender_util.h"
[email protected]cafe4ad2011-07-28 18:34:5625#include "chrome/browser/profiles/profile.h"
avi24d693f2016-08-06 18:03:5226#include "chrome/browser/task_manager/web_contents_tags.h"
[email protected]e0bc75d52014-01-30 23:42:5927#include "chrome/browser/ui/tab_helpers.h"
hashimotobf20fc62014-08-27 03:33:5728#include "chrome/browser/ui/web_contents_sizer.h"
[email protected]a0358d72012-03-09 14:06:5029#include "chrome/common/prerender_messages.h"
droger67b240c62016-08-03 11:50:2730#include "chrome/common/prerender_types.h"
John Abd-El-Malekd2377982018-01-08 22:23:1231#include "chrome/common/prerender_util.h"
sdefresnebc766ef2014-09-25 09:28:1332#include "components/history/core/browser/history_types.h"
Eric Seckler8652dcd52018-09-20 10:42:2833#include "content/public/browser/browser_task_traits.h"
[email protected]48ed2612014-01-21 00:30:5734#include "content/public/browser/browser_thread.h"
jame5626352017-01-26 20:15:2335#include "content/public/browser/navigation_handle.h"
[email protected]ad50def52011-10-19 23:17:0736#include "content/public/browser/notification_service.h"
[email protected]b849847b2013-12-10 21:57:5837#include "content/public/browser/render_frame_host.h"
[email protected]d9083482012-01-06 00:38:4638#include "content/public/browser/render_process_host.h"
[email protected]9c1662b2012-03-06 15:44:3339#include "content/public/browser/render_view_host.h"
avif9ab5d942015-10-15 14:05:4440#include "content/public/browser/render_widget_host.h"
[email protected]48055042012-07-14 21:12:1141#include "content/public/browser/session_storage_namespace.h"
[email protected]d9083482012-01-06 00:38:4642#include "content/public/browser/web_contents.h"
[email protected]674bc592011-12-20 23:00:4243#include "content/public/browser/web_contents_delegate.h"
[email protected]bde57b82013-11-01 23:10:4444#include "content/public/common/frame_navigate_params.h"
jame5626352017-01-26 20:15:2345#include "net/http/http_response_headers.h"
erikchen00e79922018-03-16 20:52:5746#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
ben03ac5d012017-04-28 05:12:5947#include "services/service_manager/public/cpp/binder_registry.h"
Sylvain Defresnec6ccc77d2014-09-19 10:19:3548#include "ui/base/page_transition_types.h"
yusufo7c8d9642016-08-22 17:41:0749#include "ui/gfx/geometry/size.h"
[email protected]33f74972010-12-08 16:40:3650
[email protected]28c5d0b72014-05-13 08:19:5951using content::BrowserThread;
[email protected]e5d549d2011-12-28 01:29:2052using content::OpenURLParams;
[email protected]eaabba22012-03-07 15:02:1153using content::RenderViewHost;
[email protected]48055042012-07-14 21:12:1154using content::SessionStorageNamespace;
[email protected]768c5472011-12-26 19:06:1755using content::WebContents;
[email protected]e582fdd2011-12-20 16:48:1756
[email protected]4c154ff82011-02-15 11:23:5957namespace prerender {
58
[email protected]5a8dffa2011-01-26 00:40:3959class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
60 public:
dcheng2c9c80c52014-10-22 21:21:0561 PrerenderContents* CreatePrerenderContents(
62 PrerenderManager* prerender_manager,
63 Profile* profile,
64 const GURL& url,
65 const content::Referrer& referrer,
Ryan Sturmd154e1e2019-06-01 01:18:5966 const base::Optional<url::Origin>& initiator_origin,
davidben569bc232015-04-21 21:25:4967 Origin origin) override {
68 return new PrerenderContents(prerender_manager, profile, url, referrer,
Ryan Sturmd154e1e2019-06-01 01:18:5969 initiator_origin, origin);
[email protected]5a8dffa2011-01-26 00:40:3970 }
71};
72
[email protected]a562aea22012-12-11 22:43:1273// WebContentsDelegateImpl -----------------------------------------------------
[email protected]d3961e82011-05-20 06:32:0374
[email protected]a562aea22012-12-11 22:43:1275class PrerenderContents::WebContentsDelegateImpl
[email protected]674bc592011-12-20 23:00:4276 : public content::WebContentsDelegate {
[email protected]d3961e82011-05-20 06:32:0377 public:
[email protected]75d90c12013-03-20 19:50:1678 explicit WebContentsDelegateImpl(PrerenderContents* prerender_contents)
79 : prerender_contents_(prerender_contents) {
[email protected]d3961e82011-05-20 06:32:0380 }
[email protected]3b023e22011-06-16 22:53:1381
[email protected]baece6c32012-06-25 21:22:4182 // content::WebContentsDelegate implementation:
dcheng2c9c80c52014-10-22 21:21:0583 WebContents* OpenURLFromTab(WebContents* source,
84 const OpenURLParams& params) override {
[email protected]0905b01662011-12-05 20:30:2285 // |OpenURLFromTab| is typically called when a frame performs a navigation
86 // that requires the browser to perform the transition instead of WebKit.
creis29460272015-12-16 04:38:2287 // Examples include client redirects to hosted app URLs.
nicka23a06d2015-06-09 18:05:4488 // TODO(cbentzel): Consider supporting this for CURRENT_TAB dispositions, if
89 // it is a common case during prerenders.
[email protected]0905b01662011-12-05 20:30:2290 prerender_contents_->Destroy(FINAL_STATUS_OPEN_URL);
91 return NULL;
92 }
93
lukasza1d025732016-09-28 21:36:0894 bool ShouldTransferNavigation(bool is_main_frame_navigation) override {
creis29460272015-12-16 04:38:2295 // Cancel the prerender if the navigation attempts to transfer to a
96 // different process. Examples include server redirects to privileged pages
97 // or cross-site subframe navigations in --site-per-process.
98 prerender_contents_->Destroy(FINAL_STATUS_OPEN_URL);
99 return false;
100 }
101
dcheng2c9c80c52014-10-22 21:21:05102 void CloseContents(content::WebContents* contents) override {
[email protected]eebe7da52014-04-30 18:00:21103 prerender_contents_->Destroy(FINAL_STATUS_CLOSED);
104 }
105
rdsmithdaa92272015-05-21 20:33:41106 void CanDownload(const GURL& url,
dcheng2c9c80c52014-10-22 21:21:05107 const std::string& request_method,
Avi Drissman346e0ea2019-04-02 00:08:46108 base::OnceCallback<void(bool)> callback) override {
[email protected]686493142011-07-15 21:47:22109 prerender_contents_->Destroy(FINAL_STATUS_DOWNLOAD);
110 // Cancel the download.
Avi Drissman346e0ea2019-04-02 00:08:46111 std::move(callback).Run(false);
[email protected]686493142011-07-15 21:47:22112 }
113
dcheng2c9c80c52014-10-22 21:21:05114 bool ShouldCreateWebContents(
nickf5e618c2016-11-28 22:38:37115 content::WebContents* web_contents,
lukasza6f8ac622017-06-06 03:10:20116 content::RenderFrameHost* opener,
nickf5e618c2016-11-28 22:38:37117 content::SiteInstance* source_site_instance,
dcheng3ce04b62015-10-26 23:30:55118 int32_t route_id,
119 int32_t main_frame_route_id,
120 int32_t main_frame_widget_route_id,
scottmgde42fb92017-02-10 17:56:03121 content::mojom::WindowContainerType window_container_type,
nickf5e618c2016-11-28 22:38:37122 const GURL& opener_url,
nasko48321ca32015-07-02 20:44:12123 const std::string& frame_name,
dcheng2c9c80c52014-10-22 21:21:05124 const GURL& target_url,
125 const std::string& partition_id,
126 SessionStorageNamespace* session_storage_namespace) override {
[email protected]f1cd3362014-01-07 20:43:01127 // Since we don't want to permit child windows that would have a
128 // window.opener property, terminate prerendering.
129 prerender_contents_->Destroy(FINAL_STATUS_CREATE_NEW_WINDOW);
130 // Cancel the popup.
131 return false;
132 }
133
dcheng2c9c80c52014-10-22 21:21:05134 bool OnGoToEntryOffset(int offset) override {
[email protected]9e1ad4b2011-08-14 16:49:19135 // This isn't allowed because the history merge operation
136 // does not work if there are renderer issued challenges.
137 // TODO(cbentzel): Cancel in this case? May not need to do
138 // since render-issued offset navigations are not guaranteed,
139 // but indicates that the page cares about the history.
140 return false;
141 }
142
mathiash72a5e462014-11-19 08:18:50143 bool ShouldSuppressDialogs(WebContents* source) override {
[email protected]baece6c32012-06-25 21:22:41144 // We still want to show the user the message when they navigate to this
145 // page, so cancel this prerender.
146 prerender_contents_->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT);
[email protected]a562aea22012-12-11 22:43:12147 // Always suppress JavaScript messages if they're triggered by a page being
148 // prerendered.
[email protected]baece6c32012-06-25 21:22:41149 return true;
150 }
151
dcheng2c9c80c52014-10-22 21:21:05152 void RegisterProtocolHandler(WebContents* web_contents,
153 const std::string& protocol,
154 const GURL& url,
155 bool user_gesture) override {
[email protected]baece6c32012-06-25 21:22:41156 // TODO(mmenke): Consider supporting this if it is a common case during
157 // prerenders.
158 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER);
[email protected]5f5b9e4cf2011-09-07 21:26:05159 }
160
Lucas Furukawa Gadani4909f3c2019-06-18 22:36:52161 gfx::Size GetSizeForNewRenderView(WebContents* web_contents) override {
[email protected]b3b0e822014-01-22 21:20:12162 // Have to set the size of the RenderView on initialization to be sure it is
163 // set before the RenderView is hidden on all platforms (esp. Android).
yusufo7c8d9642016-08-22 17:41:07164 return prerender_contents_->bounds_.size();
[email protected]b3b0e822014-01-22 21:20:12165 }
166
[email protected]d3961e82011-05-20 06:32:03167 private:
[email protected]d3961e82011-05-20 06:32:03168 PrerenderContents* prerender_contents_;
169};
170
mattcaryfb7f2b62016-10-17 08:34:35171PrerenderContents::Observer::~Observer() {}
[email protected]ac4f4682012-12-08 22:39:26172
Ryan Sturmd154e1e2019-06-01 01:18:59173PrerenderContents::PrerenderContents(
174 PrerenderManager* prerender_manager,
175 Profile* profile,
176 const GURL& url,
177 const content::Referrer& referrer,
178 const base::Optional<url::Origin>& initiator_origin,
179 Origin origin)
Egor Paskof0c11802019-03-22 13:52:31180 : prerender_mode_(DEPRECATED_FULL_PRERENDER),
mattcaryd4a8c77f2016-08-23 17:32:45181 prerendering_has_started_(false),
nigeltao98810672017-01-20 01:10:46182 prerender_canceler_binding_(this),
[email protected]115ab7b2012-05-16 20:25:59183 prerender_manager_(prerender_manager),
[email protected]33f74972010-12-08 16:40:36184 prerender_url_(url),
[email protected]608c57132011-02-16 14:57:33185 referrer_(referrer),
Ryan Sturmd154e1e2019-06-01 01:18:59186 initiator_origin_(initiator_origin),
[email protected]33f74972010-12-08 16:40:36187 profile_(profile),
[email protected]6974ae7e2012-02-16 01:17:59188 has_finished_loading_(false),
Ryan Sturm74e5c532019-04-05 23:29:47189 final_status_(FINAL_STATUS_UNKNOWN),
[email protected]e348af72011-05-23 21:02:49190 prerendering_has_been_cancelled_(false),
erikchen00e79922018-03-16 20:52:57191 process_pid_(base::kNullProcessId),
[email protected]28a05f3a2011-05-20 15:05:08192 child_id_(-1),
[email protected]86d4ff462011-05-23 17:39:37193 route_id_(-1),
[email protected]e253ab02011-07-07 21:58:39194 origin_(origin),
nigeltao98810672017-01-20 01:10:46195 network_bytes_(0),
196 weak_factory_(this) {
Ryan Sturmd154e1e2019-06-01 01:18:59197 switch (origin) {
198 case ORIGIN_OMNIBOX:
199 case ORIGIN_EXTERNAL_REQUEST:
200 case ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER:
Sofiya Semenovaece7b542019-06-19 17:26:48201 case ORIGIN_NAVIGATION_PREDICTOR:
Ryan Sturmd154e1e2019-06-01 01:18:59202 DCHECK(!initiator_origin_.has_value());
203 break;
204
205 case ORIGIN_GWS_PRERENDER:
206 case ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN:
207 case ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN:
208 case ORIGIN_LINK_REL_NEXT:
209 DCHECK(initiator_origin_.has_value());
210 break;
211 case ORIGIN_NONE:
212 case ORIGIN_MAX:
213 NOTREACHED();
214 }
215
thestigc98161a2016-07-20 01:42:49216 DCHECK(prerender_manager);
Ben Goodger9e24929e2017-07-21 03:13:40217 registry_.AddInterface(base::Bind(
218 &PrerenderContents::OnPrerenderCancelerRequest, base::Unretained(this)));
[email protected]8a6e4162011-04-27 19:36:48219}
220
221bool PrerenderContents::Init() {
[email protected]2fc4da92011-05-27 16:24:31222 return AddAliasURL(prerender_url_);
[email protected]33f74972010-12-08 16:40:36223}
224
mattcaryd4a8c77f2016-08-23 17:32:45225void PrerenderContents::SetPrerenderMode(PrerenderMode mode) {
226 DCHECK(!prerendering_has_started_);
227 prerender_mode_ = mode;
228}
229
[email protected]5a8dffa2011-01-26 00:40:39230// static
231PrerenderContents::Factory* PrerenderContents::CreateFactory() {
232 return new PrerenderContentsFactoryImpl();
233}
234
[email protected]a303db72014-01-06 05:08:19235// static
236PrerenderContents* PrerenderContents::FromWebContents(
237 content::WebContents* web_contents) {
238 if (!web_contents)
239 return NULL;
drogerc1543152016-09-20 13:03:37240 PrerenderManager* prerender_manager =
241 PrerenderManagerFactory::GetForBrowserContext(
242 web_contents->GetBrowserContext());
[email protected]a303db72014-01-06 05:08:19243 if (!prerender_manager)
244 return NULL;
245 return prerender_manager->GetPrerenderContents(web_contents);
246}
247
[email protected]71b5d242011-04-30 02:27:20248void PrerenderContents::StartPrerendering(
yusufo7c8d9642016-08-22 17:41:07249 const gfx::Rect& bounds,
davidben879199c2015-03-06 00:55:04250 SessionStorageNamespace* session_storage_namespace) {
thestigc98161a2016-07-20 01:42:49251 DCHECK(profile_);
yusufo7c8d9642016-08-22 17:41:07252 DCHECK(!bounds.IsEmpty());
[email protected]71b5d242011-04-30 02:27:20253 DCHECK(!prerendering_has_started_);
melandory1346cde2016-06-11 00:42:12254 DCHECK(!prerender_contents_);
[email protected]2736c032012-05-11 18:06:07255 DCHECK_EQ(1U, alias_urls_.size());
[email protected]71b5d242011-04-30 02:27:20256
[email protected]48055042012-07-14 21:12:11257 session_storage_namespace_id_ = session_storage_namespace->id();
yusufo7c8d9642016-08-22 17:41:07258 bounds_ = bounds;
[email protected]71b5d242011-04-30 02:27:20259
[email protected]48055042012-07-14 21:12:11260 DCHECK(load_start_time_.is_null());
261 load_start_time_ = base::TimeTicks::Now();
262
[email protected]eb9857c2012-05-29 22:50:17263 prerendering_has_started_ = true;
264
erikchenade1fef2018-05-02 22:07:57265 prerender_contents_ = CreateWebContents(session_storage_namespace);
Bryan McQuaded2b93c02017-07-14 22:26:31266 TabHelpers::AttachTabHelpers(prerender_contents_.get());
[email protected]a562aea22012-12-11 22:43:12267 content::WebContentsObserver::Observe(prerender_contents_.get());
[email protected]2736c032012-05-11 18:06:07268
afakhry674c7b12015-06-23 22:56:12269 // Tag the prerender contents with the task manager specific prerender tag, so
270 // that it shows up in the task manager.
avi24d693f2016-08-06 18:03:52271 task_manager::WebContentsTags::CreateForPrerenderContents(
afakhry674c7b12015-06-23 22:56:12272 prerender_contents_.get());
273
[email protected]a562aea22012-12-11 22:43:12274 web_contents_delegate_.reset(new WebContentsDelegateImpl(this));
275 prerender_contents_.get()->SetDelegate(web_contents_delegate_.get());
[email protected]0932b30c2012-04-17 13:25:10276 // Set the size of the prerender WebContents.
yusufo7c8d9642016-08-22 17:41:07277 ResizeWebContents(prerender_contents_.get(), bounds_);
[email protected]208ce7e2011-08-27 04:35:13278
davidben879199c2015-03-06 00:55:04279 // TODO(davidben): This logic assumes each prerender has at most one
280 // route. https://crbug.com/440544
[email protected]cfd820d2012-04-29 16:29:07281 child_id_ = GetRenderViewHost()->GetProcess()->GetID();
282 route_id_ = GetRenderViewHost()->GetRoutingID();
[email protected]ac1f70b2011-05-03 00:46:05283
davidben879199c2015-03-06 00:55:04284 // TODO(davidben): This logic assumes each prerender has at most one
285 // process. https://crbug.com/440544
[email protected]28c5d0b72014-05-13 08:19:59286 prerender_manager()->AddPrerenderProcessHost(
287 GetRenderViewHost()->GetProcess());
288
[email protected]ac4f4682012-12-08 22:39:26289 NotifyPrerenderStart();
[email protected]ac1f70b2011-05-03 00:46:05290
291 // Close ourselves when the application is shutting down.
[email protected]966c9a42012-09-25 14:40:21292 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
[email protected]ad50def52011-10-19 23:17:07293 content::NotificationService::AllSources());
[email protected]ac1f70b2011-05-03 00:46:05294
[email protected]165602b2011-05-05 14:46:52295 // Register to inform new RenderViews that we're prerendering.
296 notification_registrar_.Add(
[email protected]d53a08c2012-07-18 20:35:30297 this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED,
[email protected]a562aea22012-12-11 22:43:12298 content::Source<WebContents>(prerender_contents_.get()));
[email protected]165602b2011-05-05 14:46:52299
[email protected]bf70edce2012-06-20 22:32:22300 // Transfer over the user agent override.
[email protected]a562aea22012-12-11 22:43:12301 prerender_contents_.get()->SetUserAgentOverride(
Changwan Ryuc1134a82018-03-07 02:10:14302 prerender_manager_->config().user_agent_override, false);
[email protected]bf70edce2012-06-20 22:32:22303
[email protected]cf002332012-08-14 19:17:47304 content::NavigationController::LoadURLParams load_url_params(
305 prerender_url_);
306 load_url_params.referrer = referrer_;
Ryan Sturmd154e1e2019-06-01 01:18:59307 load_url_params.initiator_origin = initiator_origin_;
Sylvain Defresnec6ccc77d2014-09-19 10:19:35308 load_url_params.transition_type = ui::PAGE_TRANSITION_LINK;
[email protected]8b18b4a2014-02-28 05:53:49309 if (origin_ == ORIGIN_OMNIBOX) {
Sylvain Defresnec6ccc77d2014-09-19 10:19:35310 load_url_params.transition_type = ui::PageTransitionFromInt(
311 ui::PAGE_TRANSITION_TYPED |
312 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
Sofiya Semenovaece7b542019-06-19 17:26:48313 } else if (origin_ == ORIGIN_NAVIGATION_PREDICTOR) {
314 load_url_params.transition_type =
315 ui::PageTransitionFromInt(ui::PAGE_TRANSITION_GENERATED);
[email protected]8b18b4a2014-02-28 05:53:49316 }
[email protected]cf002332012-08-14 19:17:47317 load_url_params.override_user_agent =
318 prerender_manager_->config().is_overriding_user_agent ?
319 content::NavigationController::UA_OVERRIDE_TRUE :
320 content::NavigationController::UA_OVERRIDE_FALSE;
[email protected]a562aea22012-12-11 22:43:12321 prerender_contents_.get()->GetController().LoadURLWithParams(load_url_params);
[email protected]71b5d242011-04-30 02:27:20322}
323
[email protected]55e98aa2011-03-23 17:10:32324bool PrerenderContents::GetChildId(int* child_id) const {
325 CHECK(child_id);
[email protected]28a05f3a2011-05-20 15:05:08326 DCHECK_GE(child_id_, -1);
327 *child_id = child_id_;
328 return child_id_ != -1;
[email protected]55e98aa2011-03-23 17:10:32329}
330
331bool PrerenderContents::GetRouteId(int* route_id) const {
332 CHECK(route_id);
[email protected]28a05f3a2011-05-20 15:05:08333 DCHECK_GE(route_id_, -1);
334 *route_id = route_id_;
335 return route_id_ != -1;
[email protected]55e98aa2011-03-23 17:10:32336}
337
[email protected]ac4f4682012-12-08 22:39:26338void PrerenderContents::SetFinalStatus(FinalStatus final_status) {
[email protected]099d6722014-02-04 01:13:03339 DCHECK_GE(final_status, FINAL_STATUS_USED);
340 DCHECK_LT(final_status, FINAL_STATUS_MAX);
341
Ryan Sturm74e5c532019-04-05 23:29:47342 DCHECK_EQ(FINAL_STATUS_UNKNOWN, final_status_);
[email protected]ec17231bb2011-02-16 20:06:09343
[email protected]19440b22011-01-31 18:52:16344 final_status_ = final_status;
345}
346
[email protected]33f74972010-12-08 16:40:36347PrerenderContents::~PrerenderContents() {
Ryan Sturm74e5c532019-04-05 23:29:47348 DCHECK_NE(FINAL_STATUS_UNKNOWN, final_status());
[email protected]ac4f4682012-12-08 22:39:26349 DCHECK(
350 prerendering_has_been_cancelled() || final_status() == FINAL_STATUS_USED);
351 DCHECK_NE(ORIGIN_MAX, origin());
davidbenf47d1912015-03-14 00:24:24352
pasko6ee988e2016-05-12 20:23:22353 prerender_manager_->RecordFinalStatus(origin(), final_status());
Egor Paskob2d84792017-09-06 01:43:40354 prerender_manager_->RecordNetworkBytesConsumed(origin(), network_bytes_);
[email protected]3adcb412014-02-14 14:59:01355
Egor Paskof0c11802019-03-22 13:52:31356 if (prerender_mode_ == DEPRECATED_FULL_PRERENDER) {
Alexander Yashkin6b058fe2019-01-16 11:26:59357 // Broadcast the removal of aliases.
358 for (content::RenderProcessHost::iterator host_iterator =
359 content::RenderProcessHost::AllHostsIterator();
360 !host_iterator.IsAtEnd(); host_iterator.Advance()) {
361 content::RenderProcessHost* host = host_iterator.GetCurrentValue();
362 IPC::ChannelProxy* channel = host->GetChannel();
363 // |channel| might be NULL in tests.
364 if (host->IsInitializedAndNotDead() && channel) {
365 chrome::mojom::PrerenderDispatcherAssociatedPtr prerender_dispatcher;
366 channel->GetRemoteAssociatedInterface(&prerender_dispatcher);
367 prerender_dispatcher->PrerenderRemoveAliases(alias_urls_);
368 }
cm.sanchic54c9992018-01-15 05:27:24369 }
[email protected]f5b9c1b522013-05-15 09:50:10370 }
371
thestigc98161a2016-07-20 01:42:49372 if (!prerender_contents_)
373 return;
374
[email protected]0932b30c2012-04-17 13:25:10375 // If we still have a WebContents, clean up anything we need to and then
[email protected]d3c79f392011-05-20 20:04:56376 // destroy it.
thestigc98161a2016-07-20 01:42:49377 std::unique_ptr<WebContents> contents = ReleasePrerenderContents();
[email protected]33f74972010-12-08 16:40:36378}
379
[email protected]ac4f4682012-12-08 22:39:26380void PrerenderContents::AddObserver(Observer* observer) {
Ryan Sturm74e5c532019-04-05 23:29:47381 DCHECK_EQ(FINAL_STATUS_UNKNOWN, final_status_);
[email protected]ac4f4682012-12-08 22:39:26382 observer_list_.AddObserver(observer);
383}
384
[email protected]26101702012-12-15 21:45:18385void PrerenderContents::RemoveObserver(Observer* observer) {
386 observer_list_.RemoveObserver(observer);
387}
388
[email protected]432115822011-07-10 15:52:27389void PrerenderContents::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53390 const content::NotificationSource& source,
391 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27392 switch (type) {
[email protected]b9b5c5c2014-02-25 05:44:35393 // TODO(davidben): Try to remove this in favor of relying on
394 // FINAL_STATUS_PROFILE_DESTROYED.
[email protected]966c9a42012-09-25 14:40:21395 case chrome::NOTIFICATION_APP_TERMINATING:
[email protected]19440b22011-01-31 18:52:16396 Destroy(FINAL_STATUS_APP_TERMINATING);
397 return;
[email protected]549e89a2011-02-04 18:02:31398
[email protected]d53a08c2012-07-18 20:35:30399 case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: {
[email protected]165602b2011-05-05 14:46:52400 if (prerender_contents_.get()) {
[email protected]fbc5e5f92012-01-02 06:08:32401 DCHECK_EQ(content::Source<WebContents>(source).ptr(),
[email protected]a562aea22012-12-11 22:43:12402 prerender_contents_.get());
[email protected]165602b2011-05-05 14:46:52403
[email protected]6c2381d2011-10-19 02:52:53404 content::Details<RenderViewHost> new_render_view_host(details);
[email protected]b54c6c62011-05-12 15:04:04405 OnRenderViewHostCreated(new_render_view_host.ptr());
406
[email protected]5725b2e2011-09-01 13:11:27407 // Make sure the size of the RenderViewHost has been passed to the new
408 // RenderView. Otherwise, the size may not be sent until the
409 // RenderViewReady event makes it from the render process to the UI
410 // thread of the browser process. When the RenderView receives its
411 // size, is also sets itself to be visible, which would then break the
412 // visibility API.
Fady Samuel0b911822018-04-25 13:22:16413 new_render_view_host->GetWidget()->SynchronizeVisualProperties();
[email protected]a562aea22012-12-11 22:43:12414 prerender_contents_->WasHidden();
[email protected]208ce7e2011-08-27 04:35:13415 }
[email protected]5725b2e2011-09-01 13:11:27416 break;
[email protected]208ce7e2011-08-27 04:35:13417 }
418
[email protected]33f74972010-12-08 16:40:36419 default:
420 NOTREACHED() << "Unexpected notification sent.";
421 break;
422 }
423}
424
[email protected]b54c6c62011-05-12 15:04:04425void PrerenderContents::OnRenderViewHostCreated(
426 RenderViewHost* new_render_view_host) {
427}
428
erikchenade1fef2018-05-02 22:07:57429std::unique_ptr<WebContents> PrerenderContents::CreateWebContents(
[email protected]48055042012-07-14 21:12:11430 SessionStorageNamespace* session_storage_namespace) {
[email protected]fdac6ade2013-07-20 01:06:30431 // TODO(ajwong): Remove the temporary map once prerendering is aware of
432 // multiple session storage namespaces per tab.
433 content::SessionStorageNamespaceMap session_storage_namespace_map;
434 session_storage_namespace_map[std::string()] = session_storage_namespace;
Bryan McQuaded2b93c02017-07-14 22:26:31435 return WebContents::CreateWithSessionStorage(
436 WebContents::CreateParams(profile_), session_storage_namespace_map);
[email protected]de1fcdd2012-04-06 23:01:07437}
438
[email protected]ac4f4682012-12-08 22:39:26439void PrerenderContents::NotifyPrerenderStart() {
Ryan Sturm74e5c532019-04-05 23:29:47440 DCHECK_EQ(FINAL_STATUS_UNKNOWN, final_status_);
ericwilligers58b0e162016-10-21 07:15:56441 for (Observer& observer : observer_list_)
442 observer.OnPrerenderStart(this);
[email protected]ac4f4682012-12-08 22:39:26443}
444
[email protected]49fc07b2013-01-03 21:05:22445void PrerenderContents::NotifyPrerenderStopLoading() {
ericwilligers58b0e162016-10-21 07:15:56446 for (Observer& observer : observer_list_)
447 observer.OnPrerenderStopLoading(this);
[email protected]49fc07b2013-01-03 21:05:22448}
449
[email protected]59000ecd2014-02-12 00:32:04450void PrerenderContents::NotifyPrerenderDomContentLoaded() {
ericwilligers58b0e162016-10-21 07:15:56451 for (Observer& observer : observer_list_)
452 observer.OnPrerenderDomContentLoaded(this);
[email protected]59000ecd2014-02-12 00:32:04453}
454
[email protected]ac4f4682012-12-08 22:39:26455void PrerenderContents::NotifyPrerenderStop() {
Ryan Sturm74e5c532019-04-05 23:29:47456 DCHECK_NE(FINAL_STATUS_UNKNOWN, final_status_);
ericwilligers58b0e162016-10-21 07:15:56457 for (Observer& observer : observer_list_)
458 observer.OnPrerenderStop(this);
[email protected]ac4f4682012-12-08 22:39:26459 observer_list_.Clear();
460}
461
[email protected]bde57b82013-11-01 23:10:44462bool PrerenderContents::CheckURL(const GURL& url) {
[email protected]08a19e132014-01-10 18:41:45463 if (!url.SchemeIsHTTPOrHTTPS()) {
[email protected]f9034cf2011-07-21 12:43:41464 Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
465 return false;
466 }
Egor Pasko3dd9c712017-10-12 13:31:22467 if (prerender_manager_->HasRecentlyBeenNavigatedTo(origin(), url)) {
[email protected]84b5da92011-05-19 17:53:56468 Destroy(FINAL_STATUS_RECENTLY_VISITED);
469 return false;
470 }
[email protected]bde57b82013-11-01 23:10:44471 return true;
472}
473
474bool PrerenderContents::AddAliasURL(const GURL& url) {
475 if (!CheckURL(url))
476 return false;
[email protected]f9034cf2011-07-21 12:43:41477
[email protected]f39506a82011-01-18 23:46:38478 alias_urls_.push_back(url);
[email protected]f5b9c1b522013-05-15 09:50:10479
Egor Paskof0c11802019-03-22 13:52:31480 if (prerender_mode_ == DEPRECATED_FULL_PRERENDER) {
Alexander Yashkin6b058fe2019-01-16 11:26:59481 for (content::RenderProcessHost::iterator host_iterator =
482 content::RenderProcessHost::AllHostsIterator();
483 !host_iterator.IsAtEnd(); host_iterator.Advance()) {
484 content::RenderProcessHost* host = host_iterator.GetCurrentValue();
485 IPC::ChannelProxy* channel = host->GetChannel();
486 // |channel| might be NULL in tests.
487 if (host->IsInitializedAndNotDead() && channel) {
488 chrome::mojom::PrerenderDispatcherAssociatedPtr prerender_dispatcher;
489 channel->GetRemoteAssociatedInterface(&prerender_dispatcher);
490 prerender_dispatcher->PrerenderAddAlias(url);
491 }
cm.sanchic54c9992018-01-15 05:27:24492 }
[email protected]f5b9c1b522013-05-15 09:50:10493 }
494
[email protected]d085f5c2011-02-20 12:17:47495 return true;
[email protected]f39506a82011-01-18 23:46:38496}
497
[email protected]48055042012-07-14 21:12:11498bool PrerenderContents::Matches(
499 const GURL& url,
Lucas Furukawa Gadanid726e1e2019-05-08 16:20:03500 SessionStorageNamespace* session_storage_namespace) const {
davidben1f9befb2015-01-14 18:14:05501 // TODO(davidben): Remove any consumers that pass in a NULL
502 // session_storage_namespace and only test with matches.
[email protected]48055042012-07-14 21:12:11503 if (session_storage_namespace &&
[email protected]75d90c12013-03-20 19:50:16504 session_storage_namespace_id_ != session_storage_namespace->id()) {
[email protected]48055042012-07-14 21:12:11505 return false;
[email protected]75d90c12013-03-20 19:50:16506 }
Jan Wilken Dörriea8cb56302019-06-06 18:59:36507 return base::Contains(alias_urls_, url);
[email protected]f39506a82011-01-18 23:46:38508}
[email protected]973407b2011-01-26 23:18:23509
[email protected]58d5cfe2013-07-10 02:40:52510void PrerenderContents::RenderProcessGone(base::TerminationStatus status) {
pasko339bce6e2016-10-20 12:14:17511 if (status == base::TERMINATION_STATUS_STILL_RUNNING) {
512 // The renderer process is being killed because of the browser/test
513 // shutdown, before the termination notification is received.
514 Destroy(FINAL_STATUS_APP_TERMINATING);
515 }
[email protected]5ee38b882011-05-05 00:18:57516 Destroy(FINAL_STATUS_RENDERER_CRASHED);
517}
518
Ben Goodger9e24929e2017-07-21 03:13:40519void PrerenderContents::OnInterfaceRequestFromFrame(
520 content::RenderFrameHost* render_frame_host,
521 const std::string& interface_name,
522 mojo::ScopedMessagePipeHandle* interface_pipe) {
523 registry_.TryBindInterface(interface_name, interface_pipe);
524}
525
[email protected]b849847b2013-12-10 21:57:58526void PrerenderContents::RenderFrameCreated(
527 content::RenderFrameHost* render_frame_host) {
[email protected]b849847b2013-12-10 21:57:58528 // When a new RenderFrame is created for a prerendering WebContents, tell the
529 // new RenderFrame it's being used for prerendering before any navigations
530 // occur. Note that this is always triggered before the first navigation, so
531 // there's no need to send the message just after the WebContents is created.
532 render_frame_host->Send(new PrerenderMsg_SetIsPrerendering(
John Abd-El-Malekd2377982018-01-08 22:23:12533 render_frame_host->GetRoutingID(), prerender_mode_,
534 PrerenderHistograms::GetHistogramPrefix(origin_)));
[email protected]b849847b2013-12-10 21:57:58535}
536
fdegans6ce28f52015-03-19 12:52:22537void PrerenderContents::DidStopLoading() {
[email protected]49fc07b2013-01-03 21:05:22538 NotifyPrerenderStopLoading();
[email protected]973407b2011-01-26 23:18:23539}
[email protected]19440b22011-01-31 18:52:16540
[email protected]59000ecd2014-02-12 00:32:04541void PrerenderContents::DocumentLoadedInFrame(
[email protected]3619ca82014-07-09 15:45:14542 content::RenderFrameHost* render_frame_host) {
543 if (!render_frame_host->GetParent())
[email protected]59000ecd2014-02-12 00:32:04544 NotifyPrerenderDomContentLoaded();
545}
546
jame5626352017-01-26 20:15:23547void PrerenderContents::DidStartNavigation(
548 content::NavigationHandle* navigation_handle) {
eugenebuta11672fb2017-03-07 17:13:51549 if (!navigation_handle->IsInMainFrame() ||
550 navigation_handle->IsSameDocument()) {
jame5626352017-01-26 20:15:23551 return;
eugenebuta11672fb2017-03-07 17:13:51552 }
[email protected]5f5b9e4cf2011-09-07 21:26:05553
jame5626352017-01-26 20:15:23554 if (!CheckURL(navigation_handle->GetURL()))
555 return;
556
557 // Usually, this event fires if the user clicks or enters a new URL.
558 // Neither of these can happen in the case of an invisible prerender.
559 // So the cause is: Some JavaScript caused a new URL to be loaded. In that
560 // case, the spinner would start again in the browser, so we must reset
Egor Pasko7d7e5cd2018-05-28 14:54:28561 // has_finished_loading_ so that the spinner won't be stopped.
jame5626352017-01-26 20:15:23562 has_finished_loading_ = false;
[email protected]5f5b9e4cf2011-09-07 21:26:05563}
564
John Abd-El-Malekcb599d072017-11-22 21:36:00565void PrerenderContents::DidRedirectNavigation(
566 content::NavigationHandle* navigation_handle) {
567 if (!navigation_handle->IsInMainFrame())
568 return;
569
570 // If it's a redirect on the top-level resource, the name needs to be
571 // remembered for future matching, and if it redirects to an https resource,
572 // it needs to be canceled. If a subresource is redirected, nothing changes.
573 CheckURL(navigation_handle->GetURL());
574}
575
[email protected]3619ca82014-07-09 15:45:14576void PrerenderContents::DidFinishLoad(
[email protected]860234a2014-07-01 00:35:31577 content::RenderFrameHost* render_frame_host,
[email protected]3619ca82014-07-09 15:45:14578 const GURL& validated_url) {
579 if (!render_frame_host->GetParent())
[email protected]6974ae7e2012-02-16 01:17:59580 has_finished_loading_ = true;
581}
582
jame5626352017-01-26 20:15:23583void PrerenderContents::DidFinishNavigation(
584 content::NavigationHandle* navigation_handle) {
585 if (!navigation_handle->IsInMainFrame() ||
586 !navigation_handle->HasCommitted() ||
587 navigation_handle->IsErrorPage()) {
588 return;
589 }
590
591 if (navigation_handle->GetResponseHeaders() &&
592 navigation_handle->GetResponseHeaders()->response_code() >= 400) {
593 // Maintain same behavior as old navigation API when the URL is unreachable
594 // and leads to an error page. While there will be a subsequent navigation
595 // that has navigation_handle->IsErrorPage(), it'll be too late to wait for
596 // it as the renderer side will consider this prerender complete. This
597 // object would therefore have been destructed already and so instead look
598 // for the error response code now.
599 // Also maintain same final status code that previous navigation API
600 // returned, which was reached because the URL for the error page was
601 // kUnreachableWebDataURL and that was interpreted as unsupported scheme.
602 Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
603 return;
604 }
605
[email protected]ab5871b2013-11-12 20:56:55606 // If the prerender made a second navigation entry, abort the prerender. This
607 // avoids having to correctly implement a complex history merging case (this
608 // interacts with location.replace) and correctly synchronize with the
609 // renderer. The final status may be monitored to see we need to revisit this
610 // decision. This does not affect client redirects as those do not push new
611 // history entries. (Calls to location.replace, navigations before onload, and
612 // <meta http-equiv=refresh> with timeouts under 1 second do not create
613 // entries in Blink.)
614 if (prerender_contents_->GetController().GetEntryCount() > 1) {
615 Destroy(FINAL_STATUS_NEW_NAVIGATION_ENTRY);
616 return;
617 }
618
jame5626352017-01-26 20:15:23619 // Add each redirect as an alias. |navigation_handle->GetURL()| is included in
620 // |navigation_handle->GetRedirectChain()|.
[email protected]bde57b82013-11-01 23:10:44621 //
622 // TODO(davidben): We do not correctly patch up history for renderer-initated
623 // navigations which add history entries. http://crbug.com/305660.
jame5626352017-01-26 20:15:23624 for (const auto& redirect : navigation_handle->GetRedirectChain()) {
625 if (!AddAliasURL(redirect))
[email protected]bde57b82013-11-01 23:10:44626 return;
627 }
628}
629
[email protected]19440b22011-01-31 18:52:16630void PrerenderContents::Destroy(FinalStatus final_status) {
[email protected]26101702012-12-15 21:45:18631 DCHECK_NE(final_status, FINAL_STATUS_USED);
632
[email protected]e348af72011-05-23 21:02:49633 if (prerendering_has_been_cancelled_)
[email protected]5ee38b882011-05-05 00:18:57634 return;
[email protected]4c154ff82011-02-15 11:23:59635
[email protected]ac4f4682012-12-08 22:39:26636 SetFinalStatus(final_status);
[email protected]e348af72011-05-23 21:02:49637
[email protected]49308e282011-08-11 00:17:40638 prerendering_has_been_cancelled_ = true;
[email protected]128c74062012-11-27 17:55:53639 prerender_manager_->AddToHistory(this);
Egor Pasko6fed3822018-05-30 10:33:14640 prerender_manager_->SetPrefetchFinalStatusForUrl(prerender_url_,
641 final_status);
[email protected]447f9ab2011-11-14 23:56:35642 prerender_manager_->MoveEntryToPendingDelete(this, final_status);
[email protected]49308e282011-08-11 00:17:40643
droger43d1d1a2016-11-25 16:01:09644 if (prerendering_has_started())
[email protected]26101702012-12-15 21:45:18645 NotifyPrerenderStop();
[email protected]ba9f8fb2011-02-24 20:19:26646}
647
erikchen00e79922018-03-16 20:52:57648void PrerenderContents::DestroyWhenUsingTooManyResources() {
649 if (process_pid_ == base::kNullProcessId) {
Lucas Furukawa Gadani95fc3612019-04-05 22:33:49650 RenderViewHost* rvh = GetRenderViewHost();
thestig0df2bae82016-07-26 17:59:36651 if (!rvh)
erikchen00e79922018-03-16 20:52:57652 return;
thestig0df2bae82016-07-26 17:59:36653
Lucas Furukawa Gadani79951a22018-12-12 18:16:02654 content::RenderProcessHost* rph = rvh->GetProcess();
thestig0df2bae82016-07-26 17:59:36655 if (!rph)
erikchen00e79922018-03-16 20:52:57656 return;
thestig0df2bae82016-07-26 17:59:36657
Sigurdur Asgeirssoneb95666d2018-04-16 16:16:03658 base::ProcessHandle handle = rph->GetProcess().Handle();
[email protected]ba9f8fb2011-02-24 20:19:26659 if (handle == base::kNullProcessHandle)
erikchen00e79922018-03-16 20:52:57660 return;
thestig0df2bae82016-07-26 17:59:36661
Sigurdur Asgeirssoneb95666d2018-04-16 16:16:03662 process_pid_ = rph->GetProcess().Pid();
[email protected]ba9f8fb2011-02-24 20:19:26663 }
664
erikchen00e79922018-03-16 20:52:57665 if (process_pid_ == base::kNullProcessId)
[email protected]ba9f8fb2011-02-24 20:19:26666 return;
667
erikchen00e79922018-03-16 20:52:57668 // Using AdaptCallbackForRepeating allows for an easier transition to
669 // OnceCallbacks for https://crbug.com/714018.
670 memory_instrumentation::MemoryInstrumentation::GetInstance()
erikchen0c6341072018-06-15 22:05:06671 ->RequestPrivateMemoryFootprint(
672 process_pid_, base::AdaptCallbackForRepeating(base::BindOnce(
673 &PrerenderContents::DidGetMemoryUsage,
674 weak_factory_.GetWeakPtr())));
erikchen00e79922018-03-16 20:52:57675}
676
677void PrerenderContents::DidGetMemoryUsage(
678 bool success,
679 std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump) {
680 if (!success)
681 return;
682
683 for (const memory_instrumentation::GlobalMemoryDump::ProcessDump& dump :
684 global_dump->process_dumps()) {
685 if (dump.pid() != process_pid_)
686 continue;
687
688 // If |final_status_| == |FINAL_STATUS_USED|, then destruction will be
689 // handled by the entity that set final_status_.
690 if (dump.os_dump().private_footprint_kb * 1024 >
691 prerender_manager_->config().max_bytes &&
692 final_status_ != FINAL_STATUS_USED) {
693 Destroy(FINAL_STATUS_MEMORY_LIMIT_EXCEEDED);
694 }
695 return;
[email protected]ba9f8fb2011-02-24 20:19:26696 }
697}
698
thestigc98161a2016-07-20 01:42:49699std::unique_ptr<WebContents> PrerenderContents::ReleasePrerenderContents() {
700 prerender_contents_->SetDelegate(nullptr);
701 content::WebContentsObserver::Observe(nullptr);
afakhry674c7b12015-06-23 22:56:12702
703 // Clear the task manager tag we added earlier to our
704 // WebContents since it's no longer a prerender contents.
avi24d693f2016-08-06 18:03:52705 task_manager::WebContentsTags::ClearTag(prerender_contents_.get());
afakhry674c7b12015-06-23 22:56:12706
thestigc98161a2016-07-20 01:42:49707 return std::move(prerender_contents_);
[email protected]71b5d242011-04-30 02:27:20708}
709
Lucas Furukawa Gadani95fc3612019-04-05 22:33:49710RenderViewHost* PrerenderContents::GetRenderViewHost() {
thestigc98161a2016-07-20 01:42:49711 return prerender_contents_ ? prerender_contents_->GetRenderViewHost()
712 : nullptr;
[email protected]225e7432011-05-03 02:16:11713}
714
[email protected]853493a2012-09-26 02:49:42715void PrerenderContents::DidNavigate(
716 const history::HistoryAddPageArgs& add_page_args) {
717 add_page_vector_.push_back(add_page_args);
718}
719
[email protected]a562aea22012-12-11 22:43:12720void PrerenderContents::CommitHistory(WebContents* tab) {
721 HistoryTabHelper* history_tab_helper = HistoryTabHelper::FromWebContents(tab);
[email protected]853493a2012-09-26 02:49:42722 for (size_t i = 0; i < add_page_vector_.size(); ++i)
[email protected]3cbe7212012-09-28 17:02:31723 history_tab_helper->UpdateHistoryForNavigation(add_page_vector_[i]);
[email protected]d3961e82011-05-20 06:32:03724}
725
thestigc98161a2016-07-20 01:42:49726std::unique_ptr<base::DictionaryValue> PrerenderContents::GetAsValue() const {
727 if (!prerender_contents_)
728 return nullptr;
Jeremy Romanec48d7a2018-03-01 17:35:09729 auto dict_value = std::make_unique<base::DictionaryValue>();
[email protected]e2602042011-06-15 19:57:29730 dict_value->SetString("url", prerender_url_.spec());
731 base::TimeTicks current_time = base::TimeTicks::Now();
732 base::TimeDelta duration = current_time - load_start_time_;
733 dict_value->SetInteger("duration", duration.InSeconds());
[email protected]55615c62013-05-31 16:45:07734 dict_value->SetBoolean("is_loaded", prerender_contents_ &&
735 !prerender_contents_->IsLoading());
[email protected]e2602042011-06-15 19:57:29736 return dict_value;
737}
738
[email protected]099d6722014-02-04 01:13:03739void PrerenderContents::PrepareForUse() {
740 SetFinalStatus(FINAL_STATUS_USED);
741
742 if (prerender_contents_.get()) {
John Abd-El-Malekd2377982018-01-08 22:23:12743 prerender_contents_->SendToAllFrames(new PrerenderMsg_SetIsPrerendering(
744 MSG_ROUTING_NONE, NO_PRERENDER, std::string()));
[email protected]099d6722014-02-04 01:13:03745 }
746
747 NotifyPrerenderStop();
[email protected]099d6722014-02-04 01:13:03748}
749
nigeltao98810672017-01-20 01:10:46750void PrerenderContents::CancelPrerenderForPrinting() {
[email protected]8d158e092013-10-18 12:13:35751 Destroy(FINAL_STATUS_WINDOW_PRINT);
752}
[email protected]9e1ad4b2011-08-14 16:49:19753
John Abd-El-Malekd2377982018-01-08 22:23:12754void PrerenderContents::CancelPrerenderForUnsupportedMethod() {
755 Destroy(FINAL_STATUS_INVALID_HTTP_METHOD);
756}
757
758void PrerenderContents::CancelPrerenderForUnsupportedScheme(const GURL& url) {
759 Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME);
760 ReportUnsupportedPrerenderScheme(url);
761}
762
763void PrerenderContents::CancelPrerenderForSyncDeferredRedirect() {
764 Destroy(FINAL_STATUS_BAD_DEFERRED_REDIRECT);
765}
766
nigeltao98810672017-01-20 01:10:46767void PrerenderContents::OnPrerenderCancelerRequest(
768 chrome::mojom::PrerenderCancelerRequest request) {
769 if (!prerender_canceler_binding_.is_bound())
770 prerender_canceler_binding_.Bind(std::move(request));
771}
772
avib896c712015-12-26 02:10:43773void PrerenderContents::AddNetworkBytes(int64_t bytes) {
davidbenf47d1912015-03-14 00:24:24774 network_bytes_ += bytes;
dimiche932ed62017-02-24 21:38:39775 for (Observer& observer : observer_list_)
776 observer.OnPrerenderNetworkBytesChanged(this);
davidbenf47d1912015-03-14 00:24:24777}
[email protected]3adcb412014-02-14 14:59:01778
[email protected]4c154ff82011-02-15 11:23:59779} // namespace prerender