15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_contents.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <functional> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_tab_helper.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_types.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/prerender/prerender_field_trial.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_final_status.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_handle.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_render_view_host_observer.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_tracker.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_tab_contents.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/prerender_messages.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_child_process_host.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_details.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/session_storage_namespace.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/favicon_url.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadItem; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ResourceRedirectDetails; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::SessionStorageNamespace; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace prerender { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual PrerenderContents* CreatePrerenderContents( 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderManager* prerender_manager, Profile* profile, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, const content::Referrer& referrer, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Origin origin, uint8 experiment_id) OVERRIDE { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new PrerenderContents(prerender_manager, profile, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, referrer, origin, experiment_id); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebContentsDelegateImpl ----------------------------------------------------- 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrerenderContents::WebContentsDelegateImpl 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public content::WebContentsDelegate { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit WebContentsDelegateImpl(PrerenderContents* prerender_contents) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : prerender_contents_(prerender_contents) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content::WebContentsDelegate implementation: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual WebContents* OpenURLFromTab(WebContents* source, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OpenURLParams& params) OVERRIDE { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |OpenURLFromTab| is typically called when a frame performs a navigation 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that requires the browser to perform the transition instead of WebKit. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Examples include prerendering a site that redirects to an app URL, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or if --enable-strict-site-isolation is specified and the prerendered 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame redirects to a different origin. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(cbentzel): Consider supporting this if it is a common case during 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prerenders. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_contents_->Destroy(FINAL_STATUS_OPEN_URL); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void CanDownload( 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RenderViewHost* render_view_host, 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int request_id, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& request_method, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Callback<void(bool)>& callback) OVERRIDE { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_contents_->Destroy(FINAL_STATUS_DOWNLOAD); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the download. 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(false); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool ShouldCreateWebContents( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowContainerType window_container_type, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& frame_name, 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const GURL& target_url, 98a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const content::Referrer& referrer, 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch WindowOpenDisposition disposition, 100a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const WebKit::WebWindowFeatures& features, 101a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch bool user_gesture, 102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch bool opener_suppressed) OVERRIDE { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we don't want to permit child windows that would have a 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // window.opener property, terminate prerendering. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_contents_->Destroy(FINAL_STATUS_CREATE_NEW_WINDOW); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the popup. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnGoToEntryOffset(int offset) OVERRIDE { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This isn't allowed because the history merge operation 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // does not work if there are renderer issued challenges. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(cbentzel): Cancel in this case? May not need to do 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since render-issued offset navigations are not guaranteed, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but indicates that the page cares about the history. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void JSOutOfMemory(WebContents* tab) OVERRIDE { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_contents_->Destroy(FINAL_STATUS_JS_OUT_OF_MEMORY); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool ShouldSuppressDialogs() OVERRIDE { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We still want to show the user the message when they navigate to this 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // page, so cancel this prerender. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_contents_->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Always suppress JavaScript messages if they're triggered by a page being 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // prerendered. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RegisterProtocolHandler(WebContents* web_contents, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) OVERRIDE { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mmenke): Consider supporting this if it is a common case during 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prerenders. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrerenderContents* prerender_contents_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::Observer::OnPrerenderStopLoading( 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderContents* contents) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::Observer::OnPrerenderCreatedMatchCompleteReplacement( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderContents* contents, PrerenderContents* replacement) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrerenderContents::Observer::Observer() { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrerenderContents::Observer::~Observer() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<PrerenderHandle> weak_prerender_handle, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Origin origin, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::Referrer& referrer, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : weak_prerender_handle(weak_prerender_handle), 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin(origin), 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url(url), 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) referrer(referrer), 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size(size) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderContents::PendingPrerenderInfo::~PendingPrerenderInfo() { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::AddPendingPrerender( 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PendingPrerenderInfo> pending_prerender_info) { 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_prerenders_.push_back(pending_prerender_info.release()); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::PrepareForUse() { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyPrerenderStop(); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SessionStorageNamespace* session_storage_namespace = NULL; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prerender_contents_) { 186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(ajwong): This does not correctly handle storage for isolated apps. 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_storage_namespace = prerender_contents_-> 188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GetController().GetDefaultSessionStorageNamespace(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_manager_->StartPendingPrerenders( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) child_id_, &pending_prerenders_, session_storage_namespace); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_prerenders_.clear(); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderContents::PrerenderContents( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrerenderManager* prerender_manager, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::Referrer& referrer, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Origin origin, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 experiment_id) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : prerendering_has_started_(false), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_manager_(prerender_manager), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_url_(url), 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) referrer_(referrer), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(profile), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_id_(0), 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_storage_namespace_id_(-1), 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_stopped_loading_(false), 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_finished_loading_(false), 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final_status_(FINAL_STATUS_MAX), 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match_complete_status_(MATCH_COMPLETE_DEFAULT), 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerendering_has_been_cancelled_(false), 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_id_(-1), 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_(-1), 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_(origin), 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) experiment_id_(experiment_id), 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creator_child_id_(-1) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(prerender_manager != NULL); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrerenderContents* PrerenderContents::CreateMatchCompleteReplacement() { 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderContents* new_contents = prerender_manager_->CreatePrerenderContents( 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_url(), referrer(), origin(), experiment_id()); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_contents->load_start_time_ = load_start_time_; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_contents->session_storage_namespace_id_ = session_storage_namespace_id_; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_contents->set_match_complete_status( 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderContents::MATCH_COMPLETE_REPLACEMENT_PENDING); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool did_init = new_contents->Init(); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(did_init); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(alias_urls_.front(), new_contents->alias_urls_.front()); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(1u, new_contents->alias_urls_.size()); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_contents->alias_urls_ = alias_urls_; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_contents->set_match_complete_status( 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderContents::MATCH_COMPLETE_REPLACEMENT); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyPrerenderCreatedMatchCompleteReplacement(new_contents); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new_contents; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderContents::Init() { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddAliasURL(prerender_url_); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderContents::Factory* PrerenderContents::CreateFactory() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PrerenderContentsFactoryImpl(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::StartPrerendering( 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int creator_child_id, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SessionStorageNamespace* session_storage_namespace) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_ != NULL); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!size.IsEmpty()); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!prerendering_has_started_); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(prerender_contents_.get() == NULL); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(-1, creator_child_id_); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(size_.IsEmpty()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(1U, alias_urls_.size()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creator_child_id_ = creator_child_id; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_storage_namespace_id_ = session_storage_namespace->id(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = size; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(load_start_time_.is_null()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_start_time_ = base::TimeTicks::Now(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Everything after this point sets up the WebContents object and associated 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderView for the prerender page. Don't do this for members of the 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // control group. 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prerender_manager_->IsControlGroup(experiment_id())) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (origin_ == ORIGIN_LOCAL_PREDICTOR && 2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) IsLocalPredictorPrerenderAlwaysControlEnabled()) { 2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerendering_has_started_ = true; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.reset(CreateWebContents(session_storage_namespace)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserTabContents::AttachTabHelpers(prerender_contents_.get()); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delay icon fetching until the contents are getting swapped in 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to conserve network usage in mobile devices. 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper::FromWebContents( 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.get())->set_should_fetch_icons(false); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(OS_ANDROID) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::WebContentsObserver::Observe(prerender_contents_.get()); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents_delegate_.reset(new WebContentsDelegateImpl(this)); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.get()->SetDelegate(web_contents_delegate_.get()); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the size of the prerender WebContents. 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_->GetView()->SizeContents(size_); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register as an observer of the RenderViewHost so we get messages. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_observer_.reset( 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_id_ = GetRenderViewHost()->GetProcess()->GetID(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_ = GetRenderViewHost()->GetRoutingID(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register this with the ResourceDispatcherHost as a prerender 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderViewHost. This must be done before the Navigate message to catch all 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // resource requests, but as it is on the same thread as the Navigate message 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (IO) there is no race condition. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddObserver(prerender_manager()->prerender_tracker()); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyPrerenderStart(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close ourselves when the application is shutting down. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register for our parent profile to shutdown, so we can shut ourselves down 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as well (should only be called for OTR profiles, as we should receive 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // APP_TERMINATING before non-OTR profiles are destroyed). 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(tburkard): figure out if this is needed. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register to inform new RenderViews that we're prerendering. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add( 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<WebContents>(prerender_contents_.get())); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register for redirect notifications sourced from |this|. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add( 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<WebContents>(prerender_contents_.get())); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Transfer over the user agent override. 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.get()->SetUserAgentOverride( 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_manager_->config().user_agent_override); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NavigationController::LoadURLParams load_url_params( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_url_); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_url_params.referrer = referrer_; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_url_params.transition_type = (origin_ == ORIGIN_OMNIBOX ? 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_TYPED : content::PAGE_TRANSITION_LINK); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_url_params.override_user_agent = 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_manager_->config().is_overriding_user_agent ? 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NavigationController::UA_OVERRIDE_TRUE : 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NavigationController::UA_OVERRIDE_FALSE; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.get()->GetController().LoadURLWithParams(load_url_params); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderContents::GetChildId(int* child_id) const { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(child_id); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(child_id_, -1); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *child_id = child_id_; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return child_id_ != -1; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderContents::GetRouteId(int* route_id) const { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(route_id); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(route_id_, -1); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *route_id = route_id_; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return route_id_ != -1; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::SetFinalStatus(FinalStatus final_status) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(final_status_ == FINAL_STATUS_MAX); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) final_status_ = final_status; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderContents::~PrerenderContents() { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(FINAL_STATUS_MAX, final_status()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK( 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerendering_has_been_cancelled() || final_status() == FINAL_STATUS_USED); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(ORIGIN_MAX, origin()); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origin(), experiment_id(), match_complete_status(), final_status()); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Broadcast the removal of aliases. 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (content::RenderProcessHost::iterator host_iterator = 38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost::AllHostsIterator(); 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !host_iterator.IsAtEnd(); 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host_iterator.Advance()) { 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost* host = host_iterator.GetCurrentValue(); 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host->Send(new PrerenderMsg_OnPrerenderRemoveAliases(alias_urls_)); 38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we still have a WebContents, clean up anything we need to and then 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroy it. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerender_contents_.get()) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete ReleasePrerenderContents(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::AddObserver(Observer* observer) { 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(FINAL_STATUS_MAX, final_status_); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_list_.AddObserver(observer); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::RemoveObserver(Observer* observer) { 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_list_.RemoveObserver(observer); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::Observe(int type, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_PROFILE_DESTROYED: 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(FINAL_STATUS_PROFILE_DESTROYED); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_APP_TERMINATING: 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(FINAL_STATUS_APP_TERMINATING); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT: { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RESOURCE_RECEIVED_REDIRECT can come for any resource on a page. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it's a redirect on the top-level resource, the name needs 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be remembered for future matching, and if it redirects to 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an https resource, it needs to be canceled. If a subresource 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is redirected, nothing changes. 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(content::Source<WebContents>(source).ptr(), 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.get()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceRedirectDetails* resource_redirect_details = 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<ResourceRedirectDetails>(details).ptr(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(resource_redirect_details); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resource_redirect_details->resource_type == 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceType::MAIN_FRAME) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AddAliasURL(resource_redirect_details->new_url)) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_WEB_CONTENTS_RENDER_VIEW_HOST_CREATED: { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerender_contents_.get()) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(content::Source<WebContents>(source).ptr(), 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_.get()); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<RenderViewHost> new_render_view_host(details); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnRenderViewHostCreated(new_render_view_host.ptr()); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When a new RenderView is created for a prerendering WebContents, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tell the new RenderView it's being used for prerendering before any 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // navigations occur. Note that this is always triggered before the 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first navigation, so there's no need to send the message just after 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the WebContents is created. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_render_view_host->Send( 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PrerenderMsg_SetIsPrerendering( 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_render_view_host->GetRoutingID(), 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the size of the RenderViewHost has been passed to the new 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderView. Otherwise, the size may not be sent until the 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderViewReady event makes it from the render process to the UI 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread of the browser process. When the RenderView receives its 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size, is also sets itself to be visible, which would then break the 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visibility API. 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_render_view_host->WasResized(); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_->WasHidden(); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unexpected notification sent."; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::OnRenderViewHostCreated( 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* new_render_view_host) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t PrerenderContents::pending_prerender_count() const { 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pending_prerenders_.size(); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContents* PrerenderContents::CreateWebContents( 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionStorageNamespace* session_storage_namespace) { 480ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(ajwong): Remove the temporary map once prerendering is aware of 481ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // multiple session storage namespaces per tab. 482ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::SessionStorageNamespaceMap session_storage_namespace_map; 483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_storage_namespace_map[std::string()] = session_storage_namespace; 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return WebContents::CreateWithSessionStorage( 485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch WebContents::CreateParams(profile_), session_storage_namespace_map); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::NotifyPrerenderStart() { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(FINAL_STATUS_MAX, final_status_); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStart(this)); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::NotifyPrerenderStopLoading() { 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStopLoading(this)); 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::NotifyPrerenderStop() { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(FINAL_STATUS_MAX, final_status_); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStop(this)); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer_list_.Clear(); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::NotifyPrerenderCreatedMatchCompleteReplacement( 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrerenderContents* replacement) { 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(Observer, observer_list_, 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnPrerenderCreatedMatchCompleteReplacement(this, 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replacement)); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::DidUpdateFaviconURL( 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 page_id, 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<content::FaviconURL>& urls) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<content::FaviconURL>::const_iterator it = urls.begin(); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != urls.end(); ++it) { 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->icon_type == content::FaviconURL::FAVICON) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_url_ = it->icon_url; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << icon_url_; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderContents::AddAliasURL(const GURL& url) { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool http = url.SchemeIs(chrome::kHttpScheme); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool https = url.SchemeIs(chrome::kHttpsScheme); 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!http && !https) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(MATCH_COMPLETE_REPLACEMENT_PENDING, match_complete_status_); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(FINAL_STATUS_UNSUPPORTED_SCHEME); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (https && !prerender_manager_->config().https_allowed) { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(MATCH_COMPLETE_REPLACEMENT_PENDING, match_complete_status_); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(FINAL_STATUS_HTTPS); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (match_complete_status_ != MATCH_COMPLETE_REPLACEMENT_PENDING && 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_manager_->HasRecentlyBeenNavigatedTo(origin(), url)) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(FINAL_STATUS_RECENTLY_VISITED); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alias_urls_.push_back(url); 54490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 54590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (content::RenderProcessHost::iterator host_iterator = 54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost::AllHostsIterator(); 54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !host_iterator.IsAtEnd(); 54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host_iterator.Advance()) { 54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::RenderProcessHost* host = host_iterator.GetCurrentValue(); 55090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host->Send(new PrerenderMsg_OnPrerenderAddAlias(url)); 55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 55290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderContents::Matches( 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionStorageNamespace* session_storage_namespace) const { 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_storage_namespace && 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_storage_namespace_id_ != session_storage_namespace->id()) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::count_if(alias_urls_.begin(), alias_urls_.end(), 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::bind2nd(std::equal_to<GURL>(), url)) != 0; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PrerenderContents::RenderProcessGone(base::TerminationStatus status) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(FINAL_STATUS_RENDERER_CRASHED); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::DidStopLoading( 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderViewHost* render_view_host) { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_stopped_loading_ = true; 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyPrerenderStopLoading(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::DidStartProvisionalLoadForFrame( 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 frame_id, 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 parent_frame_id, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame, 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& validated_url, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_error_page, 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_iframe_srcdoc, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host) { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_main_frame) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AddAliasURL(validated_url)) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Usually, this event fires if the user clicks or enters a new URL. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Neither of these can happen in the case of an invisible prerender. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So the cause is: Some JavaScript caused a new URL to be loaded. In that 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case, the spinner would start again in the browser, so we must reset 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has_stopped_loading_ so that the spinner won't be stopped. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_stopped_loading_ = false; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_finished_loading_ = false; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::DidFinishLoad(int64 frame_id, 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& validated_url, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_main_frame, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host) { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_main_frame) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_finished_loading_ = true; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::Destroy(FinalStatus final_status) { 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(final_status, FINAL_STATUS_USED); 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerendering_has_been_cancelled_) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child_id_ != -1 && route_id_ != -1) { 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the prerender in the PrerenderTracker. This is needed 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because destroy may be called directly from the UI thread without calling 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TryCancel(). This is difficult to completely avoid, since prerendering 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can be cancelled before a RenderView is created. 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_cancelled = prerender_manager()->prerender_tracker()->TryCancel( 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_id_, route_id_, final_status); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(is_cancelled); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A different final status may have been set already from another thread. 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If so, use it instead. 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!prerender_manager()->prerender_tracker()-> 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetFinalStatus(child_id_, route_id_, &final_status)) { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetFinalStatus(final_status); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerendering_has_been_cancelled_ = true; 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_manager_->AddToHistory(this); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender_manager_->MoveEntryToPendingDelete(this, final_status); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!prerender_manager_->IsControlGroup(experiment_id()) && 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (prerendering_has_started() || 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_complete_status() == MATCH_COMPLETE_REPLACEMENT)) { 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyPrerenderStop(); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may destroy the PrerenderContents before we have initialized the 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // avoid any more messages being sent. 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (render_view_host_observer_) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_observer_->set_prerender_contents(NULL); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessMetrics* PrerenderContents::MaybeGetProcessMetrics() { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_metrics_.get() == NULL) { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a PrenderContents hasn't started prerending, don't be fully formed. 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetRenderViewHost() || !GetRenderViewHost()->GetProcess()) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle = GetRenderViewHost()->GetProcess()->GetHandle(); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle == base::kNullProcessHandle) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics( 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle, 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserChildProcessHost::GetPortProvider())); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return process_metrics_.get(); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::DestroyWhenUsingTooManyResources() { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessMetrics* metrics = MaybeGetProcessMetrics(); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (metrics == NULL) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t private_bytes, shared_bytes; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes) && 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private_bytes > prerender_manager_->config().max_bytes) { 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Destroy(FINAL_STATUS_MEMORY_LIMIT_EXCEEDED); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* PrerenderContents::ReleasePrerenderContents() { 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_->SetDelegate(NULL); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_view_host_observer_.reset(); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContentsObserver::Observe(NULL); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prerender_contents_.release(); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewHost* PrerenderContents::GetRenderViewHostMutable() { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<RenderViewHost*>(GetRenderViewHost()); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const RenderViewHost* PrerenderContents::GetRenderViewHost() const { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prerender_contents_.get()) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return prerender_contents_->GetRenderViewHost(); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderContents::DidNavigate( 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const history::HistoryAddPageArgs& add_page_args) { 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_page_vector_.push_back(add_page_args); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrerenderContents::CommitHistory(WebContents* tab) { 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HistoryTabHelper* history_tab_helper = HistoryTabHelper::FromWebContents(tab); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < add_page_vector_.size(); ++i) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_tab_helper->UpdateHistoryForNavigation(add_page_vector_[i]); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* PrerenderContents::GetAsValue() const { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prerender_contents_.get()) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict_value = new DictionaryValue(); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict_value->SetString("url", prerender_url_.spec()); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks current_time = base::TimeTicks::Now(); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta duration = current_time - load_start_time_; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict_value->SetInteger("duration", duration.InSeconds()); 716868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dict_value->SetBoolean("is_loaded", prerender_contents_ && 717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !prerender_contents_->IsLoading()); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict_value; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderContents::IsCrossSiteNavigationPending() const { 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!prerender_contents_) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (prerender_contents_->GetSiteInstance() != 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prerender_contents_->GetPendingSiteInstance()); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace prerender 730