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 PrerenderCondition; 69 class PrerenderHandle; 70 class PrerenderHistory; 71 class PrerenderLocalPredictor; 72 73 // PrerenderManager is responsible for initiating and keeping prerendered 74 // views of web pages. All methods must be called on the UI thread unless 75 // indicated otherwise. 76 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, 77 public base::NonThreadSafe, 78 public content::NotificationObserver, 79 public content::RenderProcessHostObserver, 80 public KeyedService, 81 public MediaCaptureDevicesDispatcher::Observer { 82 public: 83 // NOTE: New values need to be appended, since they are used in histograms. 84 enum PrerenderManagerMode { 85 PRERENDER_MODE_DISABLED = 0, 86 PRERENDER_MODE_ENABLED = 1, 87 PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2, 88 PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3, 89 // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4, 90 PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5, 91 PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6, 92 PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7, 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 // Set whether prerendering is currently enabled for this manager. 198 // Must be called on the UI thread. 199 // If |enabled| is false, existing prerendered pages will still persist until 200 // they time out, but new ones will not be generated. 201 void set_enabled(bool enabled); 202 203 static PrerenderManagerMode GetMode(); 204 static void SetMode(PrerenderManagerMode mode); 205 static const char* GetModeString(); 206 static bool IsPrerenderingPossible(); 207 static bool ActuallyPrerendering(); 208 static bool IsControlGroup(uint8 experiment_id); 209 static bool IsNoUseGroup(); 210 211 // Query the list of current prerender pages to see if the given web contents 212 // is prerendering a page. The optional parameter |origin| is an output 213 // parameter which, if a prerender is found, is set to the Origin of the 214 // prerender |web_contents|. 215 bool IsWebContentsPrerendering(const content::WebContents* web_contents, 216 Origin* origin) const; 217 218 // Whether the PrerenderManager has an active prerender with the given url and 219 // SessionStorageNamespace associated with the given WebContens. 220 bool HasPrerenderedUrl(GURL url, content::WebContents* web_contents) const; 221 222 // Returns the PrerenderContents object for the given web_contents, otherwise 223 // returns NULL. Note that the PrerenderContents may have been Destroy()ed, 224 // but not yet deleted. 225 PrerenderContents* GetPrerenderContents( 226 const content::WebContents* web_contents) const; 227 228 // Returns the PrerenderContents object for a given child_id, route_id pair, 229 // otherwise returns NULL. Note that the PrerenderContents may have been 230 // Destroy()ed, but not yet deleted. 231 virtual PrerenderContents* GetPrerenderContentsForRoute( 232 int child_id, int route_id) const; 233 234 // Returns a list of all WebContents being prerendered. 235 const std::vector<content::WebContents*> GetAllPrerenderingContents() const; 236 237 // Checks whether |url| has been recently navigated to. 238 bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url); 239 240 // Returns true iff the method given is valid for prerendering. 241 static bool IsValidHttpMethod(const std::string& method); 242 243 // Returns true iff the scheme of the URL given is valid for prerendering. 244 static bool DoesURLHaveValidScheme(const GURL& url); 245 246 // Returns true iff the scheme of the subresource URL given is valid for 247 // prerendering. 248 static bool DoesSubresourceURLHaveValidScheme(const GURL& url); 249 250 // Returns a Value object containing the active pages being prerendered, and 251 // a history of pages which were prerendered. The caller is responsible for 252 // deleting the return value. 253 base::DictionaryValue* GetAsValue() const; 254 255 // Clears the data indicated by which bits of clear_flags are set. 256 // 257 // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are 258 // cancelled and then deleted, and any WebContents queued for destruction are 259 // destroyed as well. 260 // 261 // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is 262 // cleared, including any entries newly created by destroying them in 263 // response to the CLEAR_PRERENDER_CONTENTS flag. 264 // 265 // Intended to be used when clearing the cache or history. 266 void ClearData(int clear_flags); 267 268 // Record a final status of a prerendered page in a histogram. 269 // This variation allows specifying whether prerendering had been started 270 // (necessary to flag MatchComplete dummies). 271 void RecordFinalStatusWithMatchCompleteStatus( 272 Origin origin, 273 uint8 experiment_id, 274 PrerenderContents::MatchCompleteStatus mc_status, 275 FinalStatus final_status) const; 276 277 // Record a cookie status histogram (see prerender_histograms.h). 278 void RecordCookieStatus(Origin origin, 279 uint8 experiment_id, 280 int cookie_status) const; 281 282 // Record a cookie send type histogram (see prerender_histograms.h). 283 void RecordCookieSendType(Origin origin, 284 uint8 experiment_id, 285 int cookie_send_type) const; 286 287 // content::NotificationObserver 288 virtual void Observe(int type, 289 const content::NotificationSource& source, 290 const content::NotificationDetails& details) OVERRIDE; 291 292 // MediaCaptureDevicesDispatcher::Observer 293 virtual void OnCreatingAudioStream(int render_process_id, 294 int render_frame_id) OVERRIDE; 295 config()296 const Config& config() const { return config_; } mutable_config()297 Config& mutable_config() { return config_; } 298 prerender_tracker()299 PrerenderTracker* prerender_tracker() { return prerender_tracker_; } 300 cookie_store_loaded()301 bool cookie_store_loaded() { return cookie_store_loaded_; } 302 303 // Adds a condition. This is owned by the PrerenderManager. 304 void AddCondition(const PrerenderCondition* condition); 305 306 // Records that some visible tab navigated (or was redirected) to the 307 // provided URL. 308 void RecordNavigation(const GURL& url); 309 310 // Updates the LoggedInPredictor state to reflect that a login has likely 311 // on the URL provided. 312 void RecordLikelyLoginOnURL(const GURL& url); 313 314 // Checks if the LoggedInPredictor shows that the user is likely logged on 315 // to the site for the URL provided. 316 void CheckIfLikelyLoggedInOnURL(const GURL& url, 317 bool* lookup_result, 318 bool* database_was_present, 319 const base::Closure& result_cb); 320 321 void OnHistoryServiceDidQueryURL(Origin origin, 322 uint8 experiment_id, 323 bool success, 324 const history::URLRow& url_row, 325 const history::VisitVector& visits); 326 profile()327 Profile* profile() const { return profile_; } 328 329 // Classes which will be tested in prerender unit browser tests should use 330 // these methods to get times for comparison, so that the test framework can 331 // mock advancing/retarding time. 332 virtual base::Time GetCurrentTime() const; 333 virtual base::TimeTicks GetCurrentTimeTicks() const; 334 335 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table()336 logged_in_predictor_table() { 337 return logged_in_predictor_table_; 338 } 339 local_predictor()340 PrerenderLocalPredictor* local_predictor() { 341 return local_predictor_.get(); 342 } 343 344 // Notification that a cookie event happened on a render frame. Will record a 345 // cookie event for a given render frame, if it is being prerendered. 346 // If cookies were sent, all cookies must be supplied in |cookie_list|. 347 static void RecordCookieEvent(int process_id, 348 int frame_id, 349 const GURL& url, 350 const GURL& frame_url, 351 bool is_for_blocking_resource, 352 PrerenderContents::CookieEvent event, 353 const net::CookieList* cookie_list); 354 355 // Arranges for all session storage merges to hang indefinitely. This is used 356 // to reliably test various swap abort cases. 357 static void HangSessionStorageMergesForTesting(); 358 359 // Notification that a prerender has completed and its bytes should be 360 // recorded. 361 void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes); 362 363 // Returns whether prerendering is currently enabled for this manager. 364 bool IsEnabled() const; 365 366 // Add to the running tally of bytes transferred over the network for this 367 // profile if prerendering is currently enabled. 368 void AddProfileNetworkBytesIfEnabled(int64 bytes); 369 370 // Registers a new ProcessHost performing a prerender. Called by 371 // PrerenderContents. 372 void AddPrerenderProcessHost(content::RenderProcessHost* process_host); 373 374 // Returns whether or not |process_host| may be reused for new navigations 375 // from a prerendering perspective. Currently, if Prerender Cookie Stores are 376 // enabled, prerenders must be in their own processes that may not be shared. 377 bool MayReuseProcessHost(content::RenderProcessHost* process_host); 378 379 // content::RenderProcessHostObserver implementation. 380 virtual void RenderProcessHostDestroyed( 381 content::RenderProcessHost* host) OVERRIDE; 382 383 // To be called once the cookie store for this profile has been loaded. 384 void OnCookieStoreLoaded(); 385 386 // For testing purposes. Issues a callback once the cookie store has been 387 // loaded. set_on_cookie_store_loaded_cb_for_testing(base::Closure cb)388 void set_on_cookie_store_loaded_cb_for_testing(base::Closure cb) { 389 on_cookie_store_loaded_cb_for_testing_ = cb; 390 } 391 392 protected: 393 class PendingSwap; 394 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> { 395 public: 396 struct OrderByExpiryTime; 397 398 PrerenderData(PrerenderManager* manager, 399 PrerenderContents* contents, 400 base::TimeTicks expiry_time); 401 402 ~PrerenderData(); 403 404 // Turn this PrerenderData into a Match Complete replacement for itself, 405 // placing the current prerender contents into |to_delete_prerenders_|. 406 void MakeIntoMatchCompleteReplacement(); 407 408 // A new PrerenderHandle has been created for this PrerenderData. 409 void OnHandleCreated(PrerenderHandle* prerender_handle); 410 411 // The launcher associated with a handle is navigating away from the context 412 // that launched this prerender. If the prerender is active, it may stay 413 // alive briefly though, in case we we going through a redirect chain that 414 // will eventually land at it. 415 void OnHandleNavigatedAway(PrerenderHandle* prerender_handle); 416 417 // The launcher associated with a handle has taken explicit action to cancel 418 // this prerender. We may well destroy the prerender in this case if no 419 // other handles continue to track it. 420 void OnHandleCanceled(PrerenderHandle* prerender_handle); 421 contents()422 PrerenderContents* contents() { return contents_.get(); } 423 424 PrerenderContents* ReleaseContents(); 425 handle_count()426 int handle_count() const { return handle_count_; } 427 abandon_time()428 base::TimeTicks abandon_time() const { return abandon_time_; } 429 expiry_time()430 base::TimeTicks expiry_time() const { return expiry_time_; } set_expiry_time(base::TimeTicks expiry_time)431 void set_expiry_time(base::TimeTicks expiry_time) { 432 expiry_time_ = expiry_time; 433 } 434 435 void ClearPendingSwap(); 436 pending_swap()437 PendingSwap* pending_swap() { return pending_swap_.get(); } set_pending_swap(PendingSwap * pending_swap)438 void set_pending_swap(PendingSwap* pending_swap) { 439 pending_swap_.reset(pending_swap); 440 } 441 442 private: 443 PrerenderManager* manager_; 444 scoped_ptr<PrerenderContents> contents_; 445 446 // The number of distinct PrerenderHandles created for |this|, including 447 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not 448 // counting the ones that have called PrerenderData::OnHandleCanceled(). For 449 // pending prerenders, this will always be 1, since the PrerenderManager 450 // only merges handles of running prerenders. 451 int handle_count_; 452 453 // The time when OnHandleNavigatedAway was called. 454 base::TimeTicks abandon_time_; 455 456 // After this time, this prerender is no longer fresh, and should be 457 // removed. 458 base::TimeTicks expiry_time_; 459 460 // If a session storage namespace merge is in progress for this object, 461 // we need to keep track of various state associated with it. 462 scoped_ptr<PendingSwap> pending_swap_; 463 464 DISALLOW_COPY_AND_ASSIGN(PrerenderData); 465 }; 466 467 // When a swap can't happen immediately, due to a sesison storage namespace 468 // merge, there will be a pending swap object while the merge is in 469 // progress. It retains all the data needed to do the merge, maintains 470 // throttles for the navigation in the target WebContents that needs to be 471 // delayed, and handles all conditions which would cancel a pending swap. 472 class PendingSwap : public content::WebContentsObserver { 473 public: 474 PendingSwap(PrerenderManager* manager, 475 content::WebContents* target_contents, 476 PrerenderData* prerender_data, 477 const GURL& url, 478 bool should_replace_current_entry); 479 virtual ~PendingSwap(); 480 481 content::WebContents* target_contents() const; set_swap_successful(bool swap_successful)482 void set_swap_successful(bool swap_successful) { 483 swap_successful_ = swap_successful; 484 } 485 486 void BeginSwap(); 487 488 // content::WebContentsObserver implementation. 489 virtual void AboutToNavigateRenderView( 490 content::RenderViewHost* render_view_host) OVERRIDE; 491 virtual void ProvisionalChangeToMainFrameUrl( 492 const GURL& url, 493 content::RenderFrameHost* render_frame_host) OVERRIDE; 494 virtual void DidCommitProvisionalLoadForFrame( 495 int64 frame_id, 496 const base::string16& frame_unique_name, 497 bool is_main_frame, 498 const GURL& validated_url, 499 content::PageTransition transition_type, 500 content::RenderViewHost* render_view_host) OVERRIDE; 501 virtual void DidFailProvisionalLoad( 502 int64 frame_id, 503 const base::string16& frame_unique_name, 504 bool is_main_frame, 505 const GURL& validated_url, 506 int error_code, 507 const base::string16& error_description, 508 content::RenderViewHost* render_view_host) OVERRIDE; 509 virtual void WebContentsDestroyed() OVERRIDE; 510 511 private: 512 void RecordEvent(PrerenderEvent event) const; 513 514 void OnMergeCompleted(content::SessionStorageNamespace::MergeResult result); 515 void OnMergeTimeout(); 516 517 // Prerender parameters. 518 PrerenderManager* manager_; 519 PrerenderData* prerender_data_; 520 GURL url_; 521 bool should_replace_current_entry_; 522 523 base::TimeTicks start_time_; 524 PrerenderTracker::ChildRouteIdPair target_route_id_; 525 bool seen_target_route_id_; 526 base::OneShotTimer<PendingSwap> merge_timeout_; 527 bool swap_successful_; 528 529 base::WeakPtrFactory<PendingSwap> weak_factory_; 530 }; 531 532 void SetPrerenderContentsFactory( 533 PrerenderContents::Factory* prerender_contents_factory); 534 535 // Called by a PrerenderData to signal that the launcher has navigated away 536 // from the context that launched the prerender. A user may have clicked 537 // a link in a page containing a <link rel=prerender> element, or the user 538 // might have committed an omnibox navigation. This is used to possibly 539 // shorten the TTL of the prerendered page. 540 void SourceNavigatedAway(PrerenderData* prerender_data); 541 542 // Gets the request context for the profile. 543 // For unit tests, this will be overriden to return NULL, since it is not 544 // needed. 545 virtual net::URLRequestContextGetter* GetURLRequestContext(); 546 547 private: 548 friend class ::InstantSearchPrerendererTest; 549 friend class PrerenderBrowserTest; 550 friend class PrerenderContents; 551 friend class PrerenderHandle; 552 friend class UnitTestPrerenderManager; 553 554 class OnCloseWebContentsDeleter; 555 struct NavigationRecord; 556 557 // Time interval before a new prerender is allowed. 558 static const int kMinTimeBetweenPrerendersMs = 500; 559 560 // Time window for which we record old navigations, in milliseconds. 561 static const int kNavigationRecordWindowMs = 5000; 562 563 void OnCancelPrerenderHandle(PrerenderData* prerender_data); 564 565 // Adds a prerender for |url| from |referrer| initiated from the process 566 // |child_id|. The |origin| specifies how the prerender was added. If |size| 567 // is empty, then PrerenderContents::StartPrerendering will instead use a 568 // default from PrerenderConfig. Returns a PrerenderHandle*, owned by the 569 // caller, or NULL. 570 PrerenderHandle* AddPrerender( 571 Origin origin, 572 int child_id, 573 const GURL& url, 574 const content::Referrer& referrer, 575 const gfx::Size& size, 576 content::SessionStorageNamespace* session_storage_namespace); 577 578 void StartSchedulingPeriodicCleanups(); 579 void StopSchedulingPeriodicCleanups(); 580 581 void EvictOldestPrerendersIfNecessary(); 582 583 // Deletes stale and cancelled prerendered PrerenderContents, as well as 584 // WebContents that have been replaced by prerendered WebContents. 585 // Also identifies and kills PrerenderContents that use too much 586 // resources. 587 void PeriodicCleanup(); 588 589 // Posts a task to call PeriodicCleanup. Results in quicker destruction of 590 // objects. If |this| is deleted before the task is run, the task will 591 // automatically be cancelled. 592 void PostCleanupTask(); 593 594 base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const; 595 base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const; 596 597 void DeleteOldEntries(); 598 virtual PrerenderContents* CreatePrerenderContents( 599 const GURL& url, 600 const content::Referrer& referrer, 601 Origin origin, 602 uint8 experiment_id); 603 604 // Insures the |active_prerenders_| are sorted by increasing expiry time. Call 605 // after every mutation of active_prerenders_ that can possibly make it 606 // unsorted (e.g. an insert, or changing an expiry time). 607 void SortActivePrerenders(); 608 609 // Finds the active PrerenderData object for a running prerender matching 610 // |url| and |session_storage_namespace|. 611 PrerenderData* FindPrerenderData( 612 const GURL& url, 613 const content::SessionStorageNamespace* session_storage_namespace); 614 615 // Finds the active PrerenderData object currently in a PendingSwap for 616 // |target_contents|. Otherwise, returns NULL. 617 PrerenderData* FindPrerenderDataForTargetContents( 618 content::WebContents* target_contents); 619 620 // Given the |prerender_contents|, find the iterator in active_prerenders_ 621 // correponding to the given prerender. 622 ScopedVector<PrerenderData>::iterator 623 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents); 624 625 bool DoesRateLimitAllowPrerender(Origin origin) const; 626 627 // Deletes old WebContents that have been replaced by prerendered ones. This 628 // is needed because they're replaced in a callback from the old WebContents, 629 // so cannot immediately be deleted. 630 void DeleteOldWebContents(); 631 632 // Cleans up old NavigationRecord's. 633 void CleanUpOldNavigations(); 634 635 // Arrange for the given WebContents to be deleted asap. If deleter is not 636 // NULL, deletes that as well. 637 void ScheduleDeleteOldWebContents(content::WebContents* tab, 638 OnCloseWebContentsDeleter* deleter); 639 640 // Adds to the history list. 641 void AddToHistory(PrerenderContents* contents); 642 643 // Returns a new Value representing the pages currently being prerendered. The 644 // caller is responsible for delete'ing the return value. 645 base::Value* GetActivePrerendersAsValue() const; 646 647 // Destroys all pending prerenders using FinalStatus. Also deletes them as 648 // well as any swapped out WebContents queued for destruction. 649 // Used both on destruction, and when clearing the browsing history. 650 void DestroyAllContents(FinalStatus final_status); 651 652 // Helper function to destroy a PrerenderContents with the specified 653 // final_status, while at the same time recording that for the MatchComplete 654 // case, that this prerender would have been used. 655 void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents, 656 FinalStatus final_status); 657 658 // Records the final status a prerender in the case that a PrerenderContents 659 // was never created, and also adds a PrerenderHistory entry. 660 // This is a helper function which will ultimately call 661 // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT. 662 void RecordFinalStatusWithoutCreatingPrerenderContents( 663 const GURL& url, Origin origin, uint8 experiment_id, 664 FinalStatus final_status) const; 665 666 667 void CookieChanged(ChromeCookieDetails* details); 668 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key, 669 bool cookies_exist); 670 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map); 671 672 void RecordEvent(PrerenderContents* contents, PrerenderEvent event) const; 673 674 // Swaps a prerender |prerender_data| for |url| into the tab, replacing 675 // |web_contents|. Returns the new WebContents that was swapped in, or NULL 676 // if a swap-in was not possible. If |should_replace_current_entry| is true, 677 // the current history entry in |web_contents| is replaced. 678 content::WebContents* SwapInternal(const GURL& url, 679 content::WebContents* web_contents, 680 PrerenderData* prerender_data, 681 bool should_replace_current_entry); 682 683 // The configuration. 684 Config config_; 685 686 // Specifies whether prerendering is currently enabled for this 687 // manager. The value can change dynamically during the lifetime 688 // of the PrerenderManager. 689 bool enabled_; 690 691 // The profile that owns this PrerenderManager. 692 Profile* profile_; 693 694 PrerenderTracker* prerender_tracker_; 695 696 // All running prerenders. Sorted by expiry time, in ascending order. 697 ScopedVector<PrerenderData> active_prerenders_; 698 699 // Prerenders awaiting deletion. 700 ScopedVector<PrerenderData> to_delete_prerenders_; 701 702 // List of recent navigations in this profile, sorted by ascending 703 // navigate_time_. 704 std::list<NavigationRecord> navigations_; 705 706 scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_; 707 708 static PrerenderManagerMode mode_; 709 710 // A count of how many prerenders we do per session. Initialized to 0 then 711 // incremented and emitted to a histogram on each successful prerender. 712 static int prerenders_per_session_count_; 713 714 // RepeatingTimer to perform periodic cleanups of pending prerendered 715 // pages. 716 base::RepeatingTimer<PrerenderManager> repeating_timer_; 717 718 // Track time of last prerender to limit prerender spam. 719 base::TimeTicks last_prerender_start_time_; 720 721 std::list<content::WebContents*> old_web_contents_list_; 722 723 ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_; 724 725 scoped_ptr<PrerenderHistory> prerender_history_; 726 727 std::list<const PrerenderCondition*> prerender_conditions_; 728 729 scoped_ptr<PrerenderHistograms> histograms_; 730 731 scoped_ptr<PrerenderLocalPredictor> local_predictor_; 732 733 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_; 734 735 // Here, we keep the logged in predictor state, but potentially a superset 736 // of its actual (database-backed) state, since we do not incorporate 737 // browser data deletion. We do not use this for actual lookups, but only 738 // to query cookie data for domains we know there was a login before. 739 // This is required to avoid a large number of cookie lookups on bulk 740 // deletion of cookies. 741 scoped_ptr<LoggedInStateMap> logged_in_state_; 742 743 content::NotificationRegistrar notification_registrar_; 744 745 base::CancelableTaskTracker query_url_tracker_; 746 747 // The number of bytes transferred over the network for the profile this 748 // PrerenderManager is attached to. 749 int64 profile_network_bytes_; 750 751 // The value of profile_network_bytes_ that was last recorded. 752 int64 last_recorded_profile_network_bytes_; 753 754 // Set of process hosts being prerendered. 755 typedef std::set<content::RenderProcessHost*> PrerenderProcessSet; 756 PrerenderProcessSet prerender_process_hosts_; 757 758 // Indicates whether the cookie store for this profile has fully loaded yet. 759 bool cookie_store_loaded_; 760 761 base::Closure on_cookie_store_loaded_cb_for_testing_; 762 763 DISALLOW_COPY_AND_ASSIGN(PrerenderManager); 764 }; 765 766 } // namespace prerender 767 768 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ 769