1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ 6 #define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ 7 8 #include <list> 9 #include <map> 10 #include <string> 11 #include <utility> 12 #include <vector> 13 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_vector.h" 17 #include "base/memory/weak_ptr.h" 18 #include "base/task/cancelable_task_tracker.h" 19 #include "base/threading/non_thread_safe.h" 20 #include "base/time/time.h" 21 #include "base/timer/timer.h" 22 #include "chrome/browser/history/history_service.h" 23 #include "chrome/browser/media/media_capture_devices_dispatcher.h" 24 #include "chrome/browser/predictors/logged_in_predictor_table.h" 25 #include "chrome/browser/prerender/prerender_config.h" 26 #include "chrome/browser/prerender/prerender_contents.h" 27 #include "chrome/browser/prerender/prerender_events.h" 28 #include "chrome/browser/prerender/prerender_final_status.h" 29 #include "chrome/browser/prerender/prerender_histograms.h" 30 #include "chrome/browser/prerender/prerender_origin.h" 31 #include "chrome/browser/prerender/prerender_tracker.h" 32 #include "components/keyed_service/core/keyed_service.h" 33 #include "content/public/browser/notification_observer.h" 34 #include "content/public/browser/notification_registrar.h" 35 #include "content/public/browser/render_process_host_observer.h" 36 #include "content/public/browser/session_storage_namespace.h" 37 #include "content/public/browser/web_contents_observer.h" 38 #include "net/cookies/canonical_cookie.h" 39 #include "net/cookies/cookie_monster.h" 40 #include "url/gurl.h" 41 42 class Profile; 43 class InstantSearchPrerendererTest; 44 struct ChromeCookieDetails; 45 46 namespace base { 47 class DictionaryValue; 48 } 49 50 namespace chrome { 51 struct NavigateParams; 52 } 53 54 namespace content { 55 class WebContents; 56 } 57 58 namespace gfx { 59 class Size; 60 } 61 62 namespace net { 63 class URLRequestContextGetter; 64 } 65 66 namespace prerender { 67 68 class PrerenderHandle; 69 class PrerenderHistory; 70 class PrerenderLocalPredictor; 71 72 // PrerenderManager is responsible for initiating and keeping prerendered 73 // views of web pages. All methods must be called on the UI thread unless 74 // indicated otherwise. 75 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, 76 public base::NonThreadSafe, 77 public content::NotificationObserver, 78 public content::RenderProcessHostObserver, 79 public KeyedService, 80 public MediaCaptureDevicesDispatcher::Observer { 81 public: 82 // NOTE: New values need to be appended, since they are used in histograms. 83 enum PrerenderManagerMode { 84 PRERENDER_MODE_DISABLED = 0, 85 PRERENDER_MODE_ENABLED = 1, 86 PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2, 87 PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3, 88 // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4, 89 PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5, 90 PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6, 91 PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7, 92 PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP = 8, 93 PRERENDER_MODE_MAX 94 }; 95 96 // One or more of these flags must be passed to ClearData() to specify just 97 // what data to clear. See function declaration for more information. 98 enum ClearFlags { 99 CLEAR_PRERENDER_CONTENTS = 0x1 << 0, 100 CLEAR_PRERENDER_HISTORY = 0x1 << 1, 101 CLEAR_MAX = 0x1 << 2 102 }; 103 104 typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap; 105 106 // ID indicating that no experiment is active. 107 static const uint8 kNoExperiment = 0; 108 109 // Owned by a Profile object for the lifetime of the profile. 110 PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker); 111 112 virtual ~PrerenderManager(); 113 114 // From KeyedService: 115 virtual void Shutdown() OVERRIDE; 116 117 // Entry points for adding prerenders. 118 119 // Adds a prerender for |url| if valid. |process_id| and |route_id| identify 120 // the RenderView that the prerender request came from. If |size| is empty, a 121 // default from the PrerenderConfig is used. Returns a caller-owned 122 // PrerenderHandle* if the URL was added, NULL if it was not. If the launching 123 // RenderView is itself prerendering, the prerender is added as a pending 124 // prerender. 125 PrerenderHandle* AddPrerenderFromLinkRelPrerender( 126 int process_id, 127 int route_id, 128 const GURL& url, 129 uint32 rel_types, 130 const content::Referrer& referrer, 131 const gfx::Size& size); 132 133 // Adds a prerender for |url| if valid. As the prerender request is coming 134 // from a source without a RenderViewHost (i.e., the omnibox) we don't have a 135 // child or route id, or a referrer. This method uses sensible values for 136 // those. The |session_storage_namespace| matches the namespace of the active 137 // tab at the time the prerender is generated from the omnibox. Returns a 138 // caller-owned PrerenderHandle*, or NULL. 139 PrerenderHandle* AddPrerenderFromOmnibox( 140 const GURL& url, 141 content::SessionStorageNamespace* session_storage_namespace, 142 const gfx::Size& size); 143 144 PrerenderHandle* AddPrerenderFromLocalPredictor( 145 const GURL& url, 146 content::SessionStorageNamespace* session_storage_namespace, 147 const gfx::Size& size); 148 149 PrerenderHandle* AddPrerenderFromExternalRequest( 150 const GURL& url, 151 const content::Referrer& referrer, 152 content::SessionStorageNamespace* session_storage_namespace, 153 const gfx::Size& size); 154 155 // Adds a prerender for Instant Search |url| if valid. The 156 // |session_storage_namespace| matches the namespace of the active tab at the 157 // time the prerender is generated. Returns a caller-owned PrerenderHandle* or 158 // NULL. 159 PrerenderHandle* AddPrerenderForInstant( 160 const GURL& url, 161 content::SessionStorageNamespace* session_storage_namespace, 162 const gfx::Size& size); 163 164 // Cancels all active prerenders. 165 void CancelAllPrerenders(); 166 167 // If |url| matches a valid prerendered page and |params| are compatible, try 168 // to swap it and merge browsing histories. Returns |true| and updates 169 // |params->target_contents| if a prerendered page is swapped in, |false| 170 // otherwise. 171 bool MaybeUsePrerenderedPage(const GURL& url, 172 chrome::NavigateParams* params); 173 174 // Moves a PrerenderContents to the pending delete list from the list of 175 // active prerenders when prerendering should be cancelled. 176 virtual void MoveEntryToPendingDelete(PrerenderContents* entry, 177 FinalStatus final_status); 178 179 // Records the page load time for a prerender that wasn't swapped in. 180 void RecordPageLoadTimeNotSwappedIn(Origin origin, 181 base::TimeDelta page_load_time, 182 const GURL& url); 183 184 // Records the perceived page load time for a page - effectively the time from 185 // when the user navigates to a page to when it finishes loading. The actual 186 // load may have started prior to navigation due to prerender hints. 187 // This must be called on the UI thread. 188 // |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value 189 // outside that range indicating that it doesn't apply. 190 void RecordPerceivedPageLoadTime( 191 Origin origin, 192 NavigationType navigation_type, 193 base::TimeDelta perceived_page_load_time, 194 double fraction_plt_elapsed_at_swap_in, 195 const GURL& url); 196 197 static PrerenderManagerMode GetMode(); 198 static void SetMode(PrerenderManagerMode mode); 199 static const char* GetModeString(); 200 static bool IsPrerenderingPossible(); 201 static bool ActuallyPrerendering(); 202 static bool IsControlGroup(uint8 experiment_id); 203 static bool IsNoUseGroup(); 204 205 // Query the list of current prerender pages to see if the given web contents 206 // is prerendering a page. The optional parameter |origin| is an output 207 // parameter which, if a prerender is found, is set to the Origin of the 208 // prerender |web_contents|. 209 bool IsWebContentsPrerendering(const content::WebContents* web_contents, 210 Origin* origin) const; 211 212 // Whether the PrerenderManager has an active prerender with the given url and 213 // SessionStorageNamespace associated with the given WebContens. 214 bool HasPrerenderedUrl(GURL url, content::WebContents* web_contents) const; 215 216 // Returns the PrerenderContents object for the given web_contents, otherwise 217 // returns NULL. Note that the PrerenderContents may have been Destroy()ed, 218 // but not yet deleted. 219 PrerenderContents* GetPrerenderContents( 220 const content::WebContents* web_contents) const; 221 222 // Returns the PrerenderContents object for a given child_id, route_id pair, 223 // otherwise returns NULL. Note that the PrerenderContents may have been 224 // Destroy()ed, but not yet deleted. 225 virtual PrerenderContents* GetPrerenderContentsForRoute( 226 int child_id, int route_id) const; 227 228 // Returns a list of all WebContents being prerendered. 229 const std::vector<content::WebContents*> GetAllPrerenderingContents() const; 230 231 // Checks whether |url| has been recently navigated to. 232 bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url); 233 234 // Returns true iff the method given is valid for prerendering. 235 static bool IsValidHttpMethod(const std::string& method); 236 237 // Returns true iff the scheme of the URL given is valid for prerendering. 238 static bool DoesURLHaveValidScheme(const GURL& url); 239 240 // Returns true iff the scheme of the subresource URL given is valid for 241 // prerendering. 242 static bool DoesSubresourceURLHaveValidScheme(const GURL& url); 243 244 // Returns a Value object containing the active pages being prerendered, and 245 // a history of pages which were prerendered. The caller is responsible for 246 // deleting the return value. 247 base::DictionaryValue* GetAsValue() const; 248 249 // Clears the data indicated by which bits of clear_flags are set. 250 // 251 // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are 252 // cancelled and then deleted, and any WebContents queued for destruction are 253 // destroyed as well. 254 // 255 // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is 256 // cleared, including any entries newly created by destroying them in 257 // response to the CLEAR_PRERENDER_CONTENTS flag. 258 // 259 // Intended to be used when clearing the cache or history. 260 void ClearData(int clear_flags); 261 262 // Record a final status of a prerendered page in a histogram. 263 // This variation allows specifying whether prerendering had been started 264 // (necessary to flag MatchComplete dummies). 265 void RecordFinalStatusWithMatchCompleteStatus( 266 Origin origin, 267 uint8 experiment_id, 268 PrerenderContents::MatchCompleteStatus mc_status, 269 FinalStatus final_status) const; 270 271 // Record a cookie status histogram (see prerender_histograms.h). 272 void RecordCookieStatus(Origin origin, 273 uint8 experiment_id, 274 int cookie_status) const; 275 276 // Record a cookie send type histogram (see prerender_histograms.h). 277 void RecordCookieSendType(Origin origin, 278 uint8 experiment_id, 279 int cookie_send_type) const; 280 281 // content::NotificationObserver 282 virtual void Observe(int type, 283 const content::NotificationSource& source, 284 const content::NotificationDetails& details) OVERRIDE; 285 286 // MediaCaptureDevicesDispatcher::Observer 287 virtual void OnCreatingAudioStream(int render_process_id, 288 int render_frame_id) OVERRIDE; 289 config()290 const Config& config() const { return config_; } mutable_config()291 Config& mutable_config() { return config_; } 292 prerender_tracker()293 PrerenderTracker* prerender_tracker() { return prerender_tracker_; } 294 cookie_store_loaded()295 bool cookie_store_loaded() { return cookie_store_loaded_; } 296 297 // Records that some visible tab navigated (or was redirected) to the 298 // provided URL. 299 void RecordNavigation(const GURL& url); 300 301 // Updates the LoggedInPredictor state to reflect that a login has likely 302 // on the URL provided. 303 void RecordLikelyLoginOnURL(const GURL& url); 304 305 // Checks if the LoggedInPredictor shows that the user is likely logged on 306 // to the site for the URL provided. 307 void CheckIfLikelyLoggedInOnURL(const GURL& url, 308 bool* lookup_result, 309 bool* database_was_present, 310 const base::Closure& result_cb); 311 312 void OnHistoryServiceDidQueryURL(Origin origin, 313 uint8 experiment_id, 314 bool success, 315 const history::URLRow& url_row, 316 const history::VisitVector& visits); 317 profile()318 Profile* profile() const { return profile_; } 319 320 // Classes which will be tested in prerender unit browser tests should use 321 // these methods to get times for comparison, so that the test framework can 322 // mock advancing/retarding time. 323 virtual base::Time GetCurrentTime() const; 324 virtual base::TimeTicks GetCurrentTimeTicks() const; 325 326 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table()327 logged_in_predictor_table() { 328 return logged_in_predictor_table_; 329 } 330 local_predictor()331 PrerenderLocalPredictor* local_predictor() { 332 return local_predictor_.get(); 333 } 334 335 // Notification that a cookie event happened on a render frame. Will record a 336 // cookie event for a given render frame, if it is being prerendered. 337 // If cookies were sent, all cookies must be supplied in |cookie_list|. 338 static void RecordCookieEvent(int process_id, 339 int frame_id, 340 const GURL& url, 341 const GURL& frame_url, 342 bool is_for_blocking_resource, 343 PrerenderContents::CookieEvent event, 344 const net::CookieList* cookie_list); 345 346 // Arranges for all session storage merges to hang indefinitely. This is used 347 // to reliably test various swap abort cases. 348 static void HangSessionStorageMergesForTesting(); 349 350 // Notification that a prerender has completed and its bytes should be 351 // recorded. 352 void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes); 353 354 // Returns whether prerendering is currently enabled for this manager. 355 bool IsEnabled() const; 356 357 // Add to the running tally of bytes transferred over the network for this 358 // profile if prerendering is currently enabled. 359 void AddProfileNetworkBytesIfEnabled(int64 bytes); 360 361 // Registers a new ProcessHost performing a prerender. Called by 362 // PrerenderContents. 363 void AddPrerenderProcessHost(content::RenderProcessHost* process_host); 364 365 // Returns whether or not |process_host| may be reused for new navigations 366 // from a prerendering perspective. Currently, if Prerender Cookie Stores are 367 // enabled, prerenders must be in their own processes that may not be shared. 368 bool MayReuseProcessHost(content::RenderProcessHost* process_host); 369 370 // content::RenderProcessHostObserver implementation. 371 virtual void RenderProcessHostDestroyed( 372 content::RenderProcessHost* host) OVERRIDE; 373 374 // To be called once the cookie store for this profile has been loaded. 375 void OnCookieStoreLoaded(); 376 377 // For testing purposes. Issues a callback once the cookie store has been 378 // loaded. set_on_cookie_store_loaded_cb_for_testing(base::Closure cb)379 void set_on_cookie_store_loaded_cb_for_testing(base::Closure cb) { 380 on_cookie_store_loaded_cb_for_testing_ = cb; 381 } 382 383 protected: 384 class PendingSwap; 385 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> { 386 public: 387 struct OrderByExpiryTime; 388 389 PrerenderData(PrerenderManager* manager, 390 PrerenderContents* contents, 391 base::TimeTicks expiry_time); 392 393 ~PrerenderData(); 394 395 // Turn this PrerenderData into a Match Complete replacement for itself, 396 // placing the current prerender contents into |to_delete_prerenders_|. 397 void MakeIntoMatchCompleteReplacement(); 398 399 // A new PrerenderHandle has been created for this PrerenderData. 400 void OnHandleCreated(PrerenderHandle* prerender_handle); 401 402 // The launcher associated with a handle is navigating away from the context 403 // that launched this prerender. If the prerender is active, it may stay 404 // alive briefly though, in case we we going through a redirect chain that 405 // will eventually land at it. 406 void OnHandleNavigatedAway(PrerenderHandle* prerender_handle); 407 408 // The launcher associated with a handle has taken explicit action to cancel 409 // this prerender. We may well destroy the prerender in this case if no 410 // other handles continue to track it. 411 void OnHandleCanceled(PrerenderHandle* prerender_handle); 412 contents()413 PrerenderContents* contents() { return contents_.get(); } 414 415 PrerenderContents* ReleaseContents(); 416 handle_count()417 int handle_count() const { return handle_count_; } 418 abandon_time()419 base::TimeTicks abandon_time() const { return abandon_time_; } 420 expiry_time()421 base::TimeTicks expiry_time() const { return expiry_time_; } set_expiry_time(base::TimeTicks expiry_time)422 void set_expiry_time(base::TimeTicks expiry_time) { 423 expiry_time_ = expiry_time; 424 } 425 426 void ClearPendingSwap(); 427 pending_swap()428 PendingSwap* pending_swap() { return pending_swap_.get(); } set_pending_swap(PendingSwap * pending_swap)429 void set_pending_swap(PendingSwap* pending_swap) { 430 pending_swap_.reset(pending_swap); 431 } 432 433 private: 434 PrerenderManager* manager_; 435 scoped_ptr<PrerenderContents> contents_; 436 437 // The number of distinct PrerenderHandles created for |this|, including 438 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not 439 // counting the ones that have called PrerenderData::OnHandleCanceled(). For 440 // pending prerenders, this will always be 1, since the PrerenderManager 441 // only merges handles of running prerenders. 442 int handle_count_; 443 444 // The time when OnHandleNavigatedAway was called. 445 base::TimeTicks abandon_time_; 446 447 // After this time, this prerender is no longer fresh, and should be 448 // removed. 449 base::TimeTicks expiry_time_; 450 451 // If a session storage namespace merge is in progress for this object, 452 // we need to keep track of various state associated with it. 453 scoped_ptr<PendingSwap> pending_swap_; 454 455 DISALLOW_COPY_AND_ASSIGN(PrerenderData); 456 }; 457 458 // When a swap can't happen immediately, due to a sesison storage namespace 459 // merge, there will be a pending swap object while the merge is in 460 // progress. It retains all the data needed to do the merge, maintains 461 // throttles for the navigation in the target WebContents that needs to be 462 // delayed, and handles all conditions which would cancel a pending swap. 463 class PendingSwap : public content::WebContentsObserver { 464 public: 465 PendingSwap(PrerenderManager* manager, 466 content::WebContents* target_contents, 467 PrerenderData* prerender_data, 468 const GURL& url, 469 bool should_replace_current_entry); 470 virtual ~PendingSwap(); 471 set_swap_successful(bool swap_successful)472 void set_swap_successful(bool swap_successful) { 473 swap_successful_ = swap_successful; 474 } 475 476 void BeginSwap(); 477 478 // content::WebContentsObserver implementation. 479 virtual void AboutToNavigateRenderView( 480 content::RenderViewHost* render_view_host) OVERRIDE; 481 virtual void DidStartProvisionalLoadForFrame( 482 content::RenderFrameHost* render_frame_host, 483 const GURL& validated_url, 484 bool is_error_page, 485 bool is_iframe_srcdoc) OVERRIDE; 486 virtual void DidCommitProvisionalLoadForFrame( 487 content::RenderFrameHost* render_frame_host, 488 const GURL& validated_url, 489 ui::PageTransition transition_type) OVERRIDE; 490 virtual void DidFailProvisionalLoad( 491 content::RenderFrameHost* render_frame_host, 492 const GURL& validated_url, 493 int error_code, 494 const base::string16& error_description) OVERRIDE; 495 virtual void WebContentsDestroyed() OVERRIDE; 496 497 private: 498 void RecordEvent(PrerenderEvent event) const; 499 500 void OnMergeCompleted(content::SessionStorageNamespace::MergeResult result); 501 void OnMergeTimeout(); 502 503 // Prerender parameters. 504 PrerenderManager* manager_; 505 PrerenderData* prerender_data_; 506 GURL url_; 507 bool should_replace_current_entry_; 508 509 base::TimeTicks start_time_; 510 PrerenderTracker::ChildRouteIdPair target_route_id_; 511 bool seen_target_route_id_; 512 base::OneShotTimer<PendingSwap> merge_timeout_; 513 bool swap_successful_; 514 515 base::WeakPtrFactory<PendingSwap> weak_factory_; 516 }; 517 518 void SetPrerenderContentsFactory( 519 PrerenderContents::Factory* prerender_contents_factory); 520 521 // Called by a PrerenderData to signal that the launcher has navigated away 522 // from the context that launched the prerender. A user may have clicked 523 // a link in a page containing a <link rel=prerender> element, or the user 524 // might have committed an omnibox navigation. This is used to possibly 525 // shorten the TTL of the prerendered page. 526 void SourceNavigatedAway(PrerenderData* prerender_data); 527 528 // Gets the request context for the profile. 529 // For unit tests, this will be overriden to return NULL, since it is not 530 // needed. 531 virtual net::URLRequestContextGetter* GetURLRequestContext(); 532 533 private: 534 friend class ::InstantSearchPrerendererTest; 535 friend class PrerenderBrowserTest; 536 friend class PrerenderContents; 537 friend class PrerenderHandle; 538 friend class UnitTestPrerenderManager; 539 540 class OnCloseWebContentsDeleter; 541 struct NavigationRecord; 542 543 // Time interval before a new prerender is allowed. 544 static const int kMinTimeBetweenPrerendersMs = 500; 545 546 // Time window for which we record old navigations, in milliseconds. 547 static const int kNavigationRecordWindowMs = 5000; 548 549 void OnCancelPrerenderHandle(PrerenderData* prerender_data); 550 551 // Adds a prerender for |url| from |referrer| initiated from the process 552 // |child_id|. The |origin| specifies how the prerender was added. If |size| 553 // is empty, then PrerenderContents::StartPrerendering will instead use a 554 // default from PrerenderConfig. Returns a PrerenderHandle*, owned by the 555 // caller, or NULL. 556 PrerenderHandle* AddPrerender( 557 Origin origin, 558 int child_id, 559 const GURL& url, 560 const content::Referrer& referrer, 561 const gfx::Size& size, 562 content::SessionStorageNamespace* session_storage_namespace); 563 564 void StartSchedulingPeriodicCleanups(); 565 void StopSchedulingPeriodicCleanups(); 566 567 void EvictOldestPrerendersIfNecessary(); 568 569 // Deletes stale and cancelled prerendered PrerenderContents, as well as 570 // WebContents that have been replaced by prerendered WebContents. 571 // Also identifies and kills PrerenderContents that use too much 572 // resources. 573 void PeriodicCleanup(); 574 575 // Posts a task to call PeriodicCleanup. Results in quicker destruction of 576 // objects. If |this| is deleted before the task is run, the task will 577 // automatically be cancelled. 578 void PostCleanupTask(); 579 580 base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const; 581 base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const; 582 583 void DeleteOldEntries(); 584 virtual PrerenderContents* CreatePrerenderContents( 585 const GURL& url, 586 const content::Referrer& referrer, 587 Origin origin, 588 uint8 experiment_id); 589 590 // Insures the |active_prerenders_| are sorted by increasing expiry time. Call 591 // after every mutation of active_prerenders_ that can possibly make it 592 // unsorted (e.g. an insert, or changing an expiry time). 593 void SortActivePrerenders(); 594 595 // Finds the active PrerenderData object for a running prerender matching 596 // |url| and |session_storage_namespace|. 597 PrerenderData* FindPrerenderData( 598 const GURL& url, 599 const content::SessionStorageNamespace* session_storage_namespace); 600 601 // Finds the active PrerenderData object currently in a PendingSwap for 602 // |target_contents|. Otherwise, returns NULL. 603 PrerenderData* FindPrerenderDataForTargetContents( 604 content::WebContents* target_contents); 605 606 // Given the |prerender_contents|, find the iterator in active_prerenders_ 607 // correponding to the given prerender. 608 ScopedVector<PrerenderData>::iterator 609 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents); 610 611 bool DoesRateLimitAllowPrerender(Origin origin) const; 612 613 // Deletes old WebContents that have been replaced by prerendered ones. This 614 // is needed because they're replaced in a callback from the old WebContents, 615 // so cannot immediately be deleted. 616 void DeleteOldWebContents(); 617 618 // Cleans up old NavigationRecord's. 619 void CleanUpOldNavigations(); 620 621 // Arrange for the given WebContents to be deleted asap. If deleter is not 622 // NULL, deletes that as well. 623 void ScheduleDeleteOldWebContents(content::WebContents* tab, 624 OnCloseWebContentsDeleter* deleter); 625 626 // Adds to the history list. 627 void AddToHistory(PrerenderContents* contents); 628 629 // Returns a new Value representing the pages currently being prerendered. The 630 // caller is responsible for delete'ing the return value. 631 base::Value* GetActivePrerendersAsValue() const; 632 633 // Destroys all pending prerenders using FinalStatus. Also deletes them as 634 // well as any swapped out WebContents queued for destruction. 635 // Used both on destruction, and when clearing the browsing history. 636 void DestroyAllContents(FinalStatus final_status); 637 638 // Helper function to destroy a PrerenderContents with the specified 639 // final_status, while at the same time recording that for the MatchComplete 640 // case, that this prerender would have been used. 641 void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents, 642 FinalStatus final_status); 643 644 // Records the final status a prerender in the case that a PrerenderContents 645 // was never created, and also adds a PrerenderHistory entry. 646 // This is a helper function which will ultimately call 647 // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT. 648 void RecordFinalStatusWithoutCreatingPrerenderContents( 649 const GURL& url, Origin origin, uint8 experiment_id, 650 FinalStatus final_status) const; 651 652 653 void CookieChanged(ChromeCookieDetails* details); 654 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key, 655 bool cookies_exist); 656 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map); 657 658 void RecordEvent(PrerenderContents* contents, PrerenderEvent event) const; 659 660 // Swaps a prerender |prerender_data| for |url| into the tab, replacing 661 // |web_contents|. Returns the new WebContents that was swapped in, or NULL 662 // if a swap-in was not possible. If |should_replace_current_entry| is true, 663 // the current history entry in |web_contents| is replaced. 664 content::WebContents* SwapInternal(const GURL& url, 665 content::WebContents* web_contents, 666 PrerenderData* prerender_data, 667 bool should_replace_current_entry); 668 669 // The configuration. 670 Config config_; 671 672 // The profile that owns this PrerenderManager. 673 Profile* profile_; 674 675 PrerenderTracker* prerender_tracker_; 676 677 // All running prerenders. Sorted by expiry time, in ascending order. 678 ScopedVector<PrerenderData> active_prerenders_; 679 680 // Prerenders awaiting deletion. 681 ScopedVector<PrerenderData> to_delete_prerenders_; 682 683 // List of recent navigations in this profile, sorted by ascending 684 // navigate_time_. 685 std::list<NavigationRecord> navigations_; 686 687 scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_; 688 689 static PrerenderManagerMode mode_; 690 691 // A count of how many prerenders we do per session. Initialized to 0 then 692 // incremented and emitted to a histogram on each successful prerender. 693 static int prerenders_per_session_count_; 694 695 // RepeatingTimer to perform periodic cleanups of pending prerendered 696 // pages. 697 base::RepeatingTimer<PrerenderManager> repeating_timer_; 698 699 // Track time of last prerender to limit prerender spam. 700 base::TimeTicks last_prerender_start_time_; 701 702 std::list<content::WebContents*> old_web_contents_list_; 703 704 ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_; 705 706 scoped_ptr<PrerenderHistory> prerender_history_; 707 708 scoped_ptr<PrerenderHistograms> histograms_; 709 710 scoped_ptr<PrerenderLocalPredictor> local_predictor_; 711 712 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_; 713 714 // Here, we keep the logged in predictor state, but potentially a superset 715 // of its actual (database-backed) state, since we do not incorporate 716 // browser data deletion. We do not use this for actual lookups, but only 717 // to query cookie data for domains we know there was a login before. 718 // This is required to avoid a large number of cookie lookups on bulk 719 // deletion of cookies. 720 scoped_ptr<LoggedInStateMap> logged_in_state_; 721 722 content::NotificationRegistrar notification_registrar_; 723 724 base::CancelableTaskTracker query_url_tracker_; 725 726 // The number of bytes transferred over the network for the profile this 727 // PrerenderManager is attached to. 728 int64 profile_network_bytes_; 729 730 // The value of profile_network_bytes_ that was last recorded. 731 int64 last_recorded_profile_network_bytes_; 732 733 // Set of process hosts being prerendered. 734 typedef std::set<content::RenderProcessHost*> PrerenderProcessSet; 735 PrerenderProcessSet prerender_process_hosts_; 736 737 // Indicates whether the cookie store for this profile has fully loaded yet. 738 bool cookie_store_loaded_; 739 740 base::Closure on_cookie_store_loaded_cb_for_testing_; 741 742 DISALLOW_COPY_AND_ASSIGN(PrerenderManager); 743 }; 744 745 } // namespace prerender 746 747 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ 748