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/containers/hash_tables.h" 15 #include "base/gtest_prod_util.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_vector.h" 18 #include "base/memory/weak_ptr.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/media/media_capture_devices_dispatcher.h" 23 #include "chrome/browser/predictors/logged_in_predictor_table.h" 24 #include "chrome/browser/prerender/prerender_config.h" 25 #include "chrome/browser/prerender/prerender_contents.h" 26 #include "chrome/browser/prerender/prerender_final_status.h" 27 #include "chrome/browser/prerender/prerender_origin.h" 28 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 29 #include "content/public/browser/notification_observer.h" 30 #include "content/public/browser/notification_registrar.h" 31 #include "net/cookies/cookie_monster.h" 32 #include "url/gurl.h" 33 34 class Profile; 35 struct ChromeCookieDetails; 36 37 namespace base { 38 class DictionaryValue; 39 } 40 41 namespace content { 42 class WebContents; 43 } 44 45 namespace gfx { 46 class Size; 47 } 48 49 namespace net { 50 class URLRequestContextGetter; 51 } 52 53 #if defined(COMPILER_GCC) 54 55 namespace BASE_HASH_NAMESPACE { 56 template <> 57 struct hash<content::WebContents*> { 58 std::size_t operator()(content::WebContents* value) const { 59 return reinterpret_cast<std::size_t>(value); 60 } 61 }; 62 63 } // namespace BASE_HASH_NAMESPACE 64 65 #endif 66 67 namespace prerender { 68 69 class PrerenderCondition; 70 class PrerenderHandle; 71 class PrerenderHistograms; 72 class PrerenderHistory; 73 class PrerenderLocalPredictor; 74 class PrerenderTracker; 75 76 // PrerenderManager is responsible for initiating and keeping prerendered 77 // views of web pages. All methods must be called on the UI thread unless 78 // indicated otherwise. 79 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, 80 public base::NonThreadSafe, 81 public content::NotificationObserver, 82 public BrowserContextKeyedService, 83 public MediaCaptureDevicesDispatcher::Observer { 84 public: 85 // NOTE: New values need to be appended, since they are used in histograms. 86 enum PrerenderManagerMode { 87 PRERENDER_MODE_DISABLED = 0, 88 PRERENDER_MODE_ENABLED = 1, 89 PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP = 2, 90 PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP = 3, 91 // Obsolete: PRERENDER_MODE_EXPERIMENT_5MIN_TTL_GROUP = 4, 92 PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP = 5, 93 PRERENDER_MODE_EXPERIMENT_MULTI_PRERENDER_GROUP = 6, 94 PRERENDER_MODE_EXPERIMENT_15MIN_TTL_GROUP = 7, 95 PRERENDER_MODE_MAX 96 }; 97 98 // One or more of these flags must be passed to ClearData() to specify just 99 // what data to clear. See function declaration for more information. 100 enum ClearFlags { 101 CLEAR_PRERENDER_CONTENTS = 0x1 << 0, 102 CLEAR_PRERENDER_HISTORY = 0x1 << 1, 103 CLEAR_MAX = 0x1 << 2 104 }; 105 106 typedef predictors::LoggedInPredictorTable::LoggedInStateMap LoggedInStateMap; 107 108 // ID indicating that no experiment is active. 109 static const uint8 kNoExperiment = 0; 110 111 // Owned by a Profile object for the lifetime of the profile. 112 PrerenderManager(Profile* profile, PrerenderTracker* prerender_tracker); 113 114 virtual ~PrerenderManager(); 115 116 // From BrowserContextKeyedService: 117 virtual void Shutdown() OVERRIDE; 118 119 // Entry points for adding prerenders. 120 121 // Adds a prerender for |url| if valid. |process_id| and |route_id| identify 122 // the RenderView that the prerender request came from. If |size| is empty, a 123 // default from the PrerenderConfig is used. Returns a caller-owned 124 // PrerenderHandle* if the URL was added, NULL if it was not. If the launching 125 // RenderView is itself prerendering, the prerender is added as a pending 126 // prerender. 127 PrerenderHandle* AddPrerenderFromLinkRelPrerender( 128 int process_id, 129 int route_id, 130 const GURL& url, 131 const content::Referrer& referrer, 132 const gfx::Size& size); 133 134 // Adds a prerender for |url| if valid. As the prerender request is coming 135 // from a source without a RenderViewHost (i.e., the omnibox) we don't have a 136 // child or route id, or a referrer. This method uses sensible values for 137 // those. The |session_storage_namespace| matches the namespace of the active 138 // tab at the time the prerender is generated from the omnibox. Returns a 139 // caller-owned PrerenderHandle*, or NULL. 140 PrerenderHandle* AddPrerenderFromOmnibox( 141 const GURL& url, 142 content::SessionStorageNamespace* session_storage_namespace, 143 const gfx::Size& size); 144 145 PrerenderHandle* AddPrerenderFromLocalPredictor( 146 const GURL& url, 147 content::SessionStorageNamespace* session_storage_namespace, 148 const gfx::Size& size); 149 150 // If |process_id| and |view_id| refer to a running prerender, destroy 151 // it with |final_status|. 152 virtual void DestroyPrerenderForRenderView(int process_id, 153 int view_id, 154 FinalStatus final_status); 155 156 // Cancels all active prerenders. 157 void CancelAllPrerenders(); 158 159 // If |url| matches a valid prerendered page, try to swap it into 160 // |web_contents| and merge browsing histories. Returns |true| if a 161 // prerendered page is swapped in, |false| otherwise. 162 bool MaybeUsePrerenderedPage(content::WebContents* web_contents, 163 const GURL& url); 164 165 // Moves a PrerenderContents to the pending delete list from the list of 166 // active prerenders when prerendering should be cancelled. 167 virtual void MoveEntryToPendingDelete(PrerenderContents* entry, 168 FinalStatus final_status); 169 170 // Records the perceived page load time for a page - effectively the time from 171 // when the user navigates to a page to when it finishes loading. The actual 172 // load may have started prior to navigation due to prerender hints. 173 // This must be called on the UI thread. 174 // |fraction_plt_elapsed_at_swap_in| must either be in [0.0, 1.0], or a value 175 // outside that range indicating that it doesn't apply. 176 static void RecordPerceivedPageLoadTime( 177 base::TimeDelta perceived_page_load_time, 178 double fraction_plt_elapsed_at_swap_in, 179 content::WebContents* web_contents, 180 const GURL& url); 181 182 // Records the percentage of pixels of the final page in place at swap-in. 183 void RecordFractionPixelsFinalAtSwapin( 184 content::WebContents* web_contents, 185 double fraction); 186 187 // Set whether prerendering is currently enabled for this manager. 188 // Must be called on the UI thread. 189 // If |enabled| is false, existing prerendered pages will still persist until 190 // they time out, but new ones will not be generated. 191 void set_enabled(bool enabled); 192 193 // Controls if we launch or squash prefetch requests as they arrive from 194 // renderers. 195 static bool IsPrefetchEnabled(); 196 static void SetIsPrefetchEnabled(bool enabled); 197 198 static PrerenderManagerMode GetMode(); 199 static void SetMode(PrerenderManagerMode mode); 200 static const char* GetModeString(); 201 static bool IsPrerenderingPossible(); 202 static bool ActuallyPrerendering(); 203 static bool IsControlGroup(uint8 experiment_id); 204 static bool IsNoUseGroup(); 205 206 // Query the list of current prerender pages to see if the given web contents 207 // is prerendering a page. The optional parameter |origin| is an output 208 // parameter which, if a prerender is found, is set to the Origin of the 209 // prerender |web_contents|. 210 bool IsWebContentsPrerendering(const content::WebContents* web_contents, 211 Origin* origin) const; 212 213 // Returns the PrerenderContents object for the given web_contents if it's 214 // used for an active prerender page, otherwise returns NULL. 215 PrerenderContents* GetPrerenderContents( 216 const content::WebContents* web_contents) const; 217 218 // Returns a list of all WebContents being prerendered. 219 const std::vector<content::WebContents*> GetAllPrerenderingContents() const; 220 221 // Maintaining and querying the set of WebContents belonging to this 222 // PrerenderManager that are currently showing prerendered pages. 223 void MarkWebContentsAsPrerendered(content::WebContents* web_contents, 224 Origin origin); 225 void MarkWebContentsAsWouldBePrerendered(content::WebContents* web_contents, 226 Origin origin); 227 void MarkWebContentsAsNotPrerendered(content::WebContents* web_contents); 228 229 // Returns true if |web_contents| was originally a prerender that has since 230 // been swapped in. The optional parameter |origin| is an output parameter 231 // which, if a prerender is found, is set to the Origin of the prerender of 232 // |web_contents|. 233 bool IsWebContentsPrerendered(content::WebContents* web_contents, 234 Origin* origin) const; 235 bool WouldWebContentsBePrerendered(content::WebContents* web_contents, 236 Origin* origin) const; 237 238 // Checks whether |url| has been recently navigated to. 239 bool HasRecentlyBeenNavigatedTo(Origin origin, const GURL& url); 240 241 // Returns true iff the method given is valid for prerendering. 242 static bool IsValidHttpMethod(const std::string& method); 243 244 // Returns true iff the scheme of the URL given is valid for prerendering. 245 static bool DoesURLHaveValidScheme(const GURL& url); 246 247 // Returns true iff the scheme of the subresource URL given is valid for 248 // prerendering. 249 static bool DoesSubresourceURLHaveValidScheme(const GURL& url); 250 251 // Returns a Value object containing the active pages being prerendered, and 252 // a history of pages which were prerendered. The caller is responsible for 253 // deleting the return value. 254 base::DictionaryValue* GetAsValue() const; 255 256 // Clears the data indicated by which bits of clear_flags are set. 257 // 258 // If the CLEAR_PRERENDER_CONTENTS bit is set, all active prerenders are 259 // cancelled and then deleted, and any WebContents queued for destruction are 260 // destroyed as well. 261 // 262 // If the CLEAR_PRERENDER_HISTORY bit is set, the prerender history is 263 // cleared, including any entries newly created by destroying them in 264 // response to the CLEAR_PRERENDER_CONTENTS flag. 265 // 266 // Intended to be used when clearing the cache or history. 267 void ClearData(int clear_flags); 268 269 // Record a final status of a prerendered page in a histogram. 270 // This variation allows specifying whether prerendering had been started 271 // (necessary to flag MatchComplete dummies). 272 void RecordFinalStatusWithMatchCompleteStatus( 273 Origin origin, 274 uint8 experiment_id, 275 PrerenderContents::MatchCompleteStatus mc_status, 276 FinalStatus final_status) const; 277 278 // content::NotificationObserver 279 virtual void Observe(int type, 280 const content::NotificationSource& source, 281 const content::NotificationDetails& details) OVERRIDE; 282 283 // MediaCaptureDevicesDispatcher::Observer 284 virtual void OnCreatingAudioStream(int render_process_id, 285 int render_view_id) OVERRIDE; 286 287 const Config& config() const { return config_; } 288 Config& mutable_config() { return config_; } 289 290 PrerenderTracker* prerender_tracker() { return prerender_tracker_; } 291 292 // Adds a condition. This is owned by the PrerenderManager. 293 void AddCondition(const PrerenderCondition* condition); 294 295 // Records that some visible tab navigated (or was redirected) to the 296 // provided URL. 297 void RecordNavigation(const GURL& url); 298 299 // Updates the LoggedInPredictor state to reflect that a login has likely 300 // on the URL provided. 301 void RecordLikelyLoginOnURL(const GURL& url); 302 303 // Checks if the LoggedInPredictor shows that the user is likely logged on 304 // to the site for the URL provided. 305 void CheckIfLikelyLoggedInOnURL(const GURL& url, 306 bool* lookup_result, 307 bool* database_was_present, 308 const base::Closure& result_cb); 309 310 Profile* profile() const { return profile_; } 311 312 // Classes which will be tested in prerender unit browser tests should use 313 // these methods to get times for comparison, so that the test framework can 314 // mock advancing/retarding time. 315 virtual base::Time GetCurrentTime() const; 316 virtual base::TimeTicks GetCurrentTimeTicks() const; 317 318 scoped_refptr<predictors::LoggedInPredictorTable> 319 logged_in_predictor_table() { 320 return logged_in_predictor_table_; 321 } 322 323 PrerenderLocalPredictor* local_predictor() { 324 return local_predictor_.get(); 325 } 326 327 protected: 328 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> { 329 public: 330 struct OrderByExpiryTime; 331 332 PrerenderData(PrerenderManager* manager, 333 PrerenderContents* contents, 334 base::TimeTicks expiry_time); 335 336 ~PrerenderData(); 337 338 // Turn this PrerenderData into a Match Complete replacement for itself, 339 // placing the current prerender contents into |to_delete_prerenders_|. 340 void MakeIntoMatchCompleteReplacement(); 341 342 // A new PrerenderHandle has been created for this PrerenderData. 343 void OnHandleCreated(PrerenderHandle* prerender_handle); 344 345 // The launcher associated with a handle is navigating away from the context 346 // that launched this prerender. If the prerender is active, it may stay 347 // alive briefly though, in case we we going through a redirect chain that 348 // will eventually land at it. 349 void OnHandleNavigatedAway(PrerenderHandle* prerender_handle); 350 351 // The launcher associated with a handle has taken explicit action to cancel 352 // this prerender. We may well destroy the prerender in this case if no 353 // other handles continue to track it. 354 void OnHandleCanceled(PrerenderHandle* prerender_handle); 355 356 PrerenderContents* contents() { return contents_.get(); } 357 358 PrerenderContents* ReleaseContents(); 359 360 int handle_count() const { return handle_count_; } 361 362 base::TimeTicks expiry_time() const { return expiry_time_; } 363 void set_expiry_time(base::TimeTicks expiry_time) { 364 expiry_time_ = expiry_time; 365 } 366 367 private: 368 PrerenderManager* manager_; 369 scoped_ptr<PrerenderContents> contents_; 370 371 // The number of distinct PrerenderHandles created for |this|, including 372 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not 373 // counting the ones that have called PrerenderData::OnHandleCanceled(). For 374 // pending prerenders, this will always be 1, since the PrerenderManager 375 // only merges handles of running prerenders. 376 int handle_count_; 377 378 // After this time, this prerender is no longer fresh, and should be 379 // removed. 380 base::TimeTicks expiry_time_; 381 382 DISALLOW_COPY_AND_ASSIGN(PrerenderData); 383 }; 384 385 void SetPrerenderContentsFactory( 386 PrerenderContents::Factory* prerender_contents_factory); 387 388 // Adds prerenders from the pending Prerenders, called by 389 // PrerenderContents::StartPendingPrerenders. 390 void StartPendingPrerenders( 391 int process_id, 392 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders, 393 content::SessionStorageNamespace* session_storage_namespace); 394 395 // Called by a PrerenderData to signal that the launcher has navigated away 396 // from the context that launched the prerender. A user may have clicked 397 // a link in a page containing a <link rel=prerender> element, or the user 398 // might have committed an omnibox navigation. This is used to possibly 399 // shorten the TTL of the prerendered page. 400 void SourceNavigatedAway(PrerenderData* prerender_data); 401 402 private: 403 friend class PrerenderBrowserTest; 404 friend class PrerenderContents; 405 friend class PrerenderHandle; 406 friend class UnitTestPrerenderManager; 407 408 class OnCloseWebContentsDeleter; 409 struct NavigationRecord; 410 411 // For each WebContents that is swapped in, we store a 412 // PrerenderedWebContentsData so that we can track the origin of the 413 // prerender. 414 struct PrerenderedWebContentsData { 415 explicit PrerenderedWebContentsData(Origin origin); 416 417 Origin origin; 418 }; 419 420 // In the control group experimental group for each WebContents "not swapped 421 // in" we create a WouldBePrerenderedWebContentsData to the origin of the 422 // "prerender" we did not launch. We also track a state machine to ensure 423 // the histogram reporting tracks what histograms would have done. 424 struct WouldBePrerenderedWebContentsData { 425 // When the WebContents gets a provisional load, we'd like to remove the 426 // WebContents from the map since the new navigation would not have swapped 427 // in a prerender. But the first provisional load after the control 428 // prerender is not "swapped in" is actually to the prerendered location! So 429 // we don't remove the item from the map on the first provisional load, but 430 // we do for subsequent loads. 431 enum State { 432 WAITING_FOR_PROVISIONAL_LOAD, 433 SEEN_PROVISIONAL_LOAD, 434 }; 435 436 explicit WouldBePrerenderedWebContentsData(Origin origin); 437 438 Origin origin; 439 State state; 440 }; 441 442 // Time interval before a new prerender is allowed. 443 static const int kMinTimeBetweenPrerendersMs = 500; 444 445 // Time window for which we record old navigations, in milliseconds. 446 static const int kNavigationRecordWindowMs = 5000; 447 448 void OnCancelPrerenderHandle(PrerenderData* prerender_data); 449 450 // Adds a prerender for |url| from |referrer| initiated from the process 451 // |child_id|. The |origin| specifies how the prerender was added. If |size| 452 // is empty, then PrerenderContents::StartPrerendering will instead use a 453 // default from PrerenderConfig. Returns a PrerenderHandle*, owned by the 454 // caller, or NULL. 455 PrerenderHandle* AddPrerender( 456 Origin origin, 457 int child_id, 458 const GURL& url, 459 const content::Referrer& referrer, 460 const gfx::Size& size, 461 content::SessionStorageNamespace* session_storage_namespace); 462 463 void StartSchedulingPeriodicCleanups(); 464 void StopSchedulingPeriodicCleanups(); 465 466 void EvictOldestPrerendersIfNecessary(); 467 468 // Deletes stale and cancelled prerendered PrerenderContents, as well as 469 // WebContents that have been replaced by prerendered WebContents. 470 // Also identifies and kills PrerenderContents that use too much 471 // resources. 472 void PeriodicCleanup(); 473 474 // Posts a task to call PeriodicCleanup. Results in quicker destruction of 475 // objects. If |this| is deleted before the task is run, the task will 476 // automatically be cancelled. 477 void PostCleanupTask(); 478 479 base::TimeTicks GetExpiryTimeForNewPrerender(Origin origin) const; 480 base::TimeTicks GetExpiryTimeForNavigatedAwayPrerender() const; 481 482 void DeleteOldEntries(); 483 virtual PrerenderContents* CreatePrerenderContents( 484 const GURL& url, 485 const content::Referrer& referrer, 486 Origin origin, 487 uint8 experiment_id); 488 489 // Insures the |active_prerenders_| are sorted by increasing expiry time. Call 490 // after every mutation of active_prerenders_ that can possibly make it 491 // unsorted (e.g. an insert, or changing an expiry time). 492 void SortActivePrerenders(); 493 494 // Finds the active PrerenderData object for a running prerender matching 495 // |url| and |session_storage_namespace|. 496 PrerenderData* FindPrerenderData( 497 const GURL& url, 498 const content::SessionStorageNamespace* session_storage_namespace); 499 500 // If |child_id| and |route_id| correspond to a RenderView that is an active 501 // prerender, returns the PrerenderData object for that prerender. Otherwise, 502 // returns NULL. 503 PrerenderData* FindPrerenderDataForChildAndRoute(int child_id, int route_id); 504 505 // Given the |prerender_contents|, find the iterator in active_prerenders_ 506 // correponding to the given prerender. 507 ScopedVector<PrerenderData>::iterator 508 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents); 509 510 bool DoesRateLimitAllowPrerender(Origin origin) const; 511 512 // Deletes old WebContents that have been replaced by prerendered ones. This 513 // is needed because they're replaced in a callback from the old WebContents, 514 // so cannot immediately be deleted. 515 void DeleteOldWebContents(); 516 517 // Cleans up old NavigationRecord's. 518 void CleanUpOldNavigations(); 519 520 // Arrange for the given WebContents to be deleted asap. If deleter is not 521 // NULL, deletes that as well. 522 void ScheduleDeleteOldWebContents(content::WebContents* tab, 523 OnCloseWebContentsDeleter* deleter); 524 525 // Adds to the history list. 526 void AddToHistory(PrerenderContents* contents); 527 528 // Returns a new Value representing the pages currently being prerendered. The 529 // caller is responsible for delete'ing the return value. 530 base::Value* GetActivePrerendersAsValue() const; 531 532 // Destroys all pending prerenders using FinalStatus. Also deletes them as 533 // well as any swapped out WebContents queued for destruction. 534 // Used both on destruction, and when clearing the browsing history. 535 void DestroyAllContents(FinalStatus final_status); 536 537 // Helper function to destroy a PrerenderContents with the specified 538 // final_status, while at the same time recording that for the MatchComplete 539 // case, that this prerender would have been used. 540 void DestroyAndMarkMatchCompleteAsUsed(PrerenderContents* prerender_contents, 541 FinalStatus final_status); 542 543 // Record a final status of a prerendered page in a histogram. 544 // This is a helper function which will ultimately call 545 // RecordFinalStatusWthMatchCompleteStatus, using MATCH_COMPLETE_DEFAULT. 546 void RecordFinalStatus(Origin origin, 547 uint8 experiment_id, 548 FinalStatus final_status) const; 549 550 // Returns whether prerendering is currently enabled for this manager. 551 // Must be called on the UI thread. 552 bool IsEnabled() const; 553 554 void CookieChanged(ChromeCookieDetails* details); 555 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key, 556 bool cookies_exist); 557 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map); 558 559 // The configuration. 560 Config config_; 561 562 // Specifies whether prerendering is currently enabled for this 563 // manager. The value can change dynamically during the lifetime 564 // of the PrerenderManager. 565 bool enabled_; 566 567 static bool is_prefetch_enabled_; 568 569 // The profile that owns this PrerenderManager. 570 Profile* profile_; 571 572 PrerenderTracker* prerender_tracker_; 573 574 // All running prerenders. Sorted by expiry time, in ascending order. 575 ScopedVector<PrerenderData> active_prerenders_; 576 577 // Prerenders awaiting deletion. 578 ScopedVector<PrerenderData> to_delete_prerenders_; 579 580 // List of recent navigations in this profile, sorted by ascending 581 // navigate_time_. 582 std::list<NavigationRecord> navigations_; 583 584 // This map is from all WebContents which are currently displaying a 585 // prerendered page which has already been swapped in to a 586 // PrerenderedWebContentsData for tracking full lifetime information 587 // on prerenders. 588 base::hash_map<content::WebContents*, PrerenderedWebContentsData> 589 prerendered_web_contents_data_; 590 591 // WebContents that would have been swapped out for a prerendered WebContents 592 // if the user was not part of the control group for measurement. When the 593 // WebContents gets a provisional load, the WebContents is removed from 594 // the map since the new navigation would not have swapped in a prerender. 595 // However, one complication exists because the first provisional load after 596 // the WebContents is marked as "Would Have Been Prerendered" is actually to 597 // the prerendered location. So, we need to keep a state around that does 598 // not clear the item from the map on the first provisional load, but does 599 // for subsequent loads. 600 base::hash_map<content::WebContents*, WouldBePrerenderedWebContentsData> 601 would_be_prerendered_map_; 602 603 scoped_ptr<PrerenderContents::Factory> prerender_contents_factory_; 604 605 static PrerenderManagerMode mode_; 606 607 // A count of how many prerenders we do per session. Initialized to 0 then 608 // incremented and emitted to a histogram on each successful prerender. 609 static int prerenders_per_session_count_; 610 611 // RepeatingTimer to perform periodic cleanups of pending prerendered 612 // pages. 613 base::RepeatingTimer<PrerenderManager> repeating_timer_; 614 615 // Track time of last prerender to limit prerender spam. 616 base::TimeTicks last_prerender_start_time_; 617 618 std::list<content::WebContents*> old_web_contents_list_; 619 620 ScopedVector<OnCloseWebContentsDeleter> on_close_web_contents_deleters_; 621 622 scoped_ptr<PrerenderHistory> prerender_history_; 623 624 std::list<const PrerenderCondition*> prerender_conditions_; 625 626 scoped_ptr<PrerenderHistograms> histograms_; 627 628 scoped_ptr<PrerenderLocalPredictor> local_predictor_; 629 630 scoped_refptr<predictors::LoggedInPredictorTable> logged_in_predictor_table_; 631 632 // Here, we keep the logged in predictor state, but potentially a superset 633 // of its actual (database-backed) state, since we do not incorporate 634 // browser data deletion. We do not use this for actual lookups, but only 635 // to query cookie data for domains we know there was a login before. 636 // This is required to avoid a large number of cookie lookups on bulk 637 // deletion of cookies. 638 scoped_ptr<LoggedInStateMap> logged_in_state_; 639 640 content::NotificationRegistrar notification_registrar_; 641 642 DISALLOW_COPY_AND_ASSIGN(PrerenderManager); 643 }; 644 645 PrerenderManager* FindPrerenderManagerUsingRenderProcessId( 646 int render_process_id); 647 648 } // namespace prerender 649 650 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ 651