| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ | 5 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ |
| 6 #define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ | 6 #define CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ |
| 7 | 7 |
| 8 #include <list> | 8 #include <list> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
| 17 #include "base/memory/weak_ptr.h" | 17 #include "base/memory/weak_ptr.h" |
| 18 #include "base/task/cancelable_task_tracker.h" | 18 #include "base/task/cancelable_task_tracker.h" |
| 19 #include "base/threading/non_thread_safe.h" | 19 #include "base/threading/non_thread_safe.h" |
| 20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 21 #include "base/timer/timer.h" | 21 #include "base/timer/timer.h" |
| 22 #include "chrome/browser/history/history_service.h" | 22 #include "chrome/browser/history/history_service.h" |
| 23 #include "chrome/browser/media/media_capture_devices_dispatcher.h" | 23 #include "chrome/browser/media/media_capture_devices_dispatcher.h" |
| 24 #include "chrome/browser/predictors/logged_in_predictor_table.h" | 24 #include "chrome/browser/predictors/logged_in_predictor_table.h" |
| 25 #include "chrome/browser/prerender/prerender_config.h" | 25 #include "chrome/browser/prerender/prerender_config.h" |
| 26 #include "chrome/browser/prerender/prerender_contents.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" | 27 #include "chrome/browser/prerender/prerender_final_status.h" |
| 29 #include "chrome/browser/prerender/prerender_histograms.h" | 28 #include "chrome/browser/prerender/prerender_histograms.h" |
| 30 #include "chrome/browser/prerender/prerender_origin.h" | 29 #include "chrome/browser/prerender/prerender_origin.h" |
| 31 #include "chrome/browser/prerender/prerender_tracker.h" | |
| 32 #include "components/keyed_service/core/keyed_service.h" | 30 #include "components/keyed_service/core/keyed_service.h" |
| 33 #include "content/public/browser/notification_observer.h" | 31 #include "content/public/browser/notification_observer.h" |
| 34 #include "content/public/browser/notification_registrar.h" | 32 #include "content/public/browser/notification_registrar.h" |
| 35 #include "content/public/browser/render_process_host_observer.h" | 33 #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" | 34 #include "net/cookies/canonical_cookie.h" |
| 39 #include "net/cookies/cookie_monster.h" | 35 #include "net/cookies/cookie_monster.h" |
| 40 #include "url/gurl.h" | 36 #include "url/gurl.h" |
| 41 | 37 |
| 42 class Profile; | 38 class Profile; |
| 43 class InstantSearchPrerendererTest; | 39 class InstantSearchPrerendererTest; |
| 44 struct ChromeCookieDetails; | 40 struct ChromeCookieDetails; |
| 45 | 41 |
| 46 namespace base { | 42 namespace base { |
| 47 class DictionaryValue; | 43 class DictionaryValue; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 61 | 57 |
| 62 namespace net { | 58 namespace net { |
| 63 class URLRequestContextGetter; | 59 class URLRequestContextGetter; |
| 64 } | 60 } |
| 65 | 61 |
| 66 namespace prerender { | 62 namespace prerender { |
| 67 | 63 |
| 68 class PrerenderHandle; | 64 class PrerenderHandle; |
| 69 class PrerenderHistory; | 65 class PrerenderHistory; |
| 70 class PrerenderLocalPredictor; | 66 class PrerenderLocalPredictor; |
| 67 class PrerenderTracker; |
| 71 | 68 |
| 72 // PrerenderManager is responsible for initiating and keeping prerendered | 69 // PrerenderManager is responsible for initiating and keeping prerendered |
| 73 // views of web pages. All methods must be called on the UI thread unless | 70 // views of web pages. All methods must be called on the UI thread unless |
| 74 // indicated otherwise. | 71 // indicated otherwise. |
| 75 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, | 72 class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, |
| 76 public base::NonThreadSafe, | 73 public base::NonThreadSafe, |
| 77 public content::NotificationObserver, | 74 public content::NotificationObserver, |
| 78 public content::RenderProcessHostObserver, | 75 public content::RenderProcessHostObserver, |
| 79 public KeyedService, | 76 public KeyedService, |
| 80 public MediaCaptureDevicesDispatcher::Observer { | 77 public MediaCaptureDevicesDispatcher::Observer { |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 // cookie event for a given render frame, if it is being prerendered. | 333 // 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|. | 334 // If cookies were sent, all cookies must be supplied in |cookie_list|. |
| 338 static void RecordCookieEvent(int process_id, | 335 static void RecordCookieEvent(int process_id, |
| 339 int frame_id, | 336 int frame_id, |
| 340 const GURL& url, | 337 const GURL& url, |
| 341 const GURL& frame_url, | 338 const GURL& frame_url, |
| 342 bool is_for_blocking_resource, | 339 bool is_for_blocking_resource, |
| 343 PrerenderContents::CookieEvent event, | 340 PrerenderContents::CookieEvent event, |
| 344 const net::CookieList* cookie_list); | 341 const net::CookieList* cookie_list); |
| 345 | 342 |
| 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 | 343 // Notification that a prerender has completed and its bytes should be |
| 351 // recorded. | 344 // recorded. |
| 352 void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes); | 345 void RecordNetworkBytes(Origin origin, bool used, int64 prerender_bytes); |
| 353 | 346 |
| 354 // Returns whether prerendering is currently enabled for this manager. | 347 // Returns whether prerendering is currently enabled for this manager. |
| 355 bool IsEnabled() const; | 348 bool IsEnabled() const; |
| 356 | 349 |
| 357 // Add to the running tally of bytes transferred over the network for this | 350 // Add to the running tally of bytes transferred over the network for this |
| 358 // profile if prerendering is currently enabled. | 351 // profile if prerendering is currently enabled. |
| 359 void AddProfileNetworkBytesIfEnabled(int64 bytes); | 352 void AddProfileNetworkBytesIfEnabled(int64 bytes); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 373 // To be called once the cookie store for this profile has been loaded. | 366 // To be called once the cookie store for this profile has been loaded. |
| 374 void OnCookieStoreLoaded(); | 367 void OnCookieStoreLoaded(); |
| 375 | 368 |
| 376 // For testing purposes. Issues a callback once the cookie store has been | 369 // For testing purposes. Issues a callback once the cookie store has been |
| 377 // loaded. | 370 // loaded. |
| 378 void set_on_cookie_store_loaded_cb_for_testing(base::Closure cb) { | 371 void set_on_cookie_store_loaded_cb_for_testing(base::Closure cb) { |
| 379 on_cookie_store_loaded_cb_for_testing_ = cb; | 372 on_cookie_store_loaded_cb_for_testing_ = cb; |
| 380 } | 373 } |
| 381 | 374 |
| 382 protected: | 375 protected: |
| 383 class PendingSwap; | |
| 384 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> { | 376 class PrerenderData : public base::SupportsWeakPtr<PrerenderData> { |
| 385 public: | 377 public: |
| 386 struct OrderByExpiryTime; | 378 struct OrderByExpiryTime; |
| 387 | 379 |
| 388 PrerenderData(PrerenderManager* manager, | 380 PrerenderData(PrerenderManager* manager, |
| 389 PrerenderContents* contents, | 381 PrerenderContents* contents, |
| 390 base::TimeTicks expiry_time); | 382 base::TimeTicks expiry_time); |
| 391 | 383 |
| 392 ~PrerenderData(); | 384 ~PrerenderData(); |
| 393 | 385 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 415 | 407 |
| 416 int handle_count() const { return handle_count_; } | 408 int handle_count() const { return handle_count_; } |
| 417 | 409 |
| 418 base::TimeTicks abandon_time() const { return abandon_time_; } | 410 base::TimeTicks abandon_time() const { return abandon_time_; } |
| 419 | 411 |
| 420 base::TimeTicks expiry_time() const { return expiry_time_; } | 412 base::TimeTicks expiry_time() const { return expiry_time_; } |
| 421 void set_expiry_time(base::TimeTicks expiry_time) { | 413 void set_expiry_time(base::TimeTicks expiry_time) { |
| 422 expiry_time_ = expiry_time; | 414 expiry_time_ = expiry_time; |
| 423 } | 415 } |
| 424 | 416 |
| 425 void ClearPendingSwap(); | |
| 426 | |
| 427 PendingSwap* pending_swap() { return pending_swap_.get(); } | |
| 428 void set_pending_swap(PendingSwap* pending_swap) { | |
| 429 pending_swap_.reset(pending_swap); | |
| 430 } | |
| 431 | |
| 432 private: | 417 private: |
| 433 PrerenderManager* manager_; | 418 PrerenderManager* manager_; |
| 434 scoped_ptr<PrerenderContents> contents_; | 419 scoped_ptr<PrerenderContents> contents_; |
| 435 | 420 |
| 436 // The number of distinct PrerenderHandles created for |this|, including | 421 // The number of distinct PrerenderHandles created for |this|, including |
| 437 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not | 422 // ones that have called PrerenderData::OnHandleNavigatedAway(), but not |
| 438 // counting the ones that have called PrerenderData::OnHandleCanceled(). For | 423 // counting the ones that have called PrerenderData::OnHandleCanceled(). For |
| 439 // pending prerenders, this will always be 1, since the PrerenderManager | 424 // pending prerenders, this will always be 1, since the PrerenderManager |
| 440 // only merges handles of running prerenders. | 425 // only merges handles of running prerenders. |
| 441 int handle_count_; | 426 int handle_count_; |
| 442 | 427 |
| 443 // The time when OnHandleNavigatedAway was called. | 428 // The time when OnHandleNavigatedAway was called. |
| 444 base::TimeTicks abandon_time_; | 429 base::TimeTicks abandon_time_; |
| 445 | 430 |
| 446 // After this time, this prerender is no longer fresh, and should be | 431 // After this time, this prerender is no longer fresh, and should be |
| 447 // removed. | 432 // removed. |
| 448 base::TimeTicks expiry_time_; | 433 base::TimeTicks expiry_time_; |
| 449 | 434 |
| 450 // If a session storage namespace merge is in progress for this object, | |
| 451 // we need to keep track of various state associated with it. | |
| 452 scoped_ptr<PendingSwap> pending_swap_; | |
| 453 | |
| 454 DISALLOW_COPY_AND_ASSIGN(PrerenderData); | 435 DISALLOW_COPY_AND_ASSIGN(PrerenderData); |
| 455 }; | 436 }; |
| 456 | 437 |
| 457 // When a swap can't happen immediately, due to a sesison storage namespace | |
| 458 // merge, there will be a pending swap object while the merge is in | |
| 459 // progress. It retains all the data needed to do the merge, maintains | |
| 460 // throttles for the navigation in the target WebContents that needs to be | |
| 461 // delayed, and handles all conditions which would cancel a pending swap. | |
| 462 class PendingSwap : public content::WebContentsObserver { | |
| 463 public: | |
| 464 PendingSwap(PrerenderManager* manager, | |
| 465 content::WebContents* target_contents, | |
| 466 PrerenderData* prerender_data, | |
| 467 const GURL& url, | |
| 468 bool should_replace_current_entry); | |
| 469 ~PendingSwap() override; | |
| 470 | |
| 471 void set_swap_successful(bool swap_successful) { | |
| 472 swap_successful_ = swap_successful; | |
| 473 } | |
| 474 | |
| 475 void BeginSwap(); | |
| 476 | |
| 477 // content::WebContentsObserver implementation. | |
| 478 void AboutToNavigateRenderFrame( | |
| 479 content::RenderFrameHost* render_frame_host) override; | |
| 480 void DidStartProvisionalLoadForFrame( | |
| 481 content::RenderFrameHost* render_frame_host, | |
| 482 const GURL& validated_url, | |
| 483 bool is_error_page, | |
| 484 bool is_iframe_srcdoc) override; | |
| 485 void DidCommitProvisionalLoadForFrame( | |
| 486 content::RenderFrameHost* render_frame_host, | |
| 487 const GURL& validated_url, | |
| 488 ui::PageTransition transition_type) override; | |
| 489 void DidFailProvisionalLoad( | |
| 490 content::RenderFrameHost* render_frame_host, | |
| 491 const GURL& validated_url, | |
| 492 int error_code, | |
| 493 const base::string16& error_description) override; | |
| 494 void WebContentsDestroyed() override; | |
| 495 | |
| 496 private: | |
| 497 void RecordEvent(PrerenderEvent event) const; | |
| 498 | |
| 499 void OnMergeCompleted(content::SessionStorageNamespace::MergeResult result); | |
| 500 void OnMergeTimeout(); | |
| 501 | |
| 502 // Prerender parameters. | |
| 503 PrerenderManager* manager_; | |
| 504 PrerenderData* prerender_data_; | |
| 505 GURL url_; | |
| 506 bool should_replace_current_entry_; | |
| 507 | |
| 508 base::TimeTicks start_time_; | |
| 509 PrerenderTracker::ChildRouteIdPair target_route_id_; | |
| 510 bool seen_target_route_id_; | |
| 511 base::OneShotTimer<PendingSwap> merge_timeout_; | |
| 512 bool swap_successful_; | |
| 513 | |
| 514 base::WeakPtrFactory<PendingSwap> weak_factory_; | |
| 515 }; | |
| 516 | |
| 517 void SetPrerenderContentsFactory( | 438 void SetPrerenderContentsFactory( |
| 518 PrerenderContents::Factory* prerender_contents_factory); | 439 PrerenderContents::Factory* prerender_contents_factory); |
| 519 | 440 |
| 520 // Called by a PrerenderData to signal that the launcher has navigated away | 441 // Called by a PrerenderData to signal that the launcher has navigated away |
| 521 // from the context that launched the prerender. A user may have clicked | 442 // from the context that launched the prerender. A user may have clicked |
| 522 // a link in a page containing a <link rel=prerender> element, or the user | 443 // a link in a page containing a <link rel=prerender> element, or the user |
| 523 // might have committed an omnibox navigation. This is used to possibly | 444 // might have committed an omnibox navigation. This is used to possibly |
| 524 // shorten the TTL of the prerendered page. | 445 // shorten the TTL of the prerendered page. |
| 525 void SourceNavigatedAway(PrerenderData* prerender_data); | 446 void SourceNavigatedAway(PrerenderData* prerender_data); |
| 526 | 447 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 // after every mutation of active_prerenders_ that can possibly make it | 509 // after every mutation of active_prerenders_ that can possibly make it |
| 589 // unsorted (e.g. an insert, or changing an expiry time). | 510 // unsorted (e.g. an insert, or changing an expiry time). |
| 590 void SortActivePrerenders(); | 511 void SortActivePrerenders(); |
| 591 | 512 |
| 592 // Finds the active PrerenderData object for a running prerender matching | 513 // Finds the active PrerenderData object for a running prerender matching |
| 593 // |url| and |session_storage_namespace|. | 514 // |url| and |session_storage_namespace|. |
| 594 PrerenderData* FindPrerenderData( | 515 PrerenderData* FindPrerenderData( |
| 595 const GURL& url, | 516 const GURL& url, |
| 596 const content::SessionStorageNamespace* session_storage_namespace); | 517 const content::SessionStorageNamespace* session_storage_namespace); |
| 597 | 518 |
| 598 // Finds the active PrerenderData object currently in a PendingSwap for | |
| 599 // |target_contents|. Otherwise, returns NULL. | |
| 600 PrerenderData* FindPrerenderDataForTargetContents( | |
| 601 content::WebContents* target_contents); | |
| 602 | |
| 603 // Given the |prerender_contents|, find the iterator in active_prerenders_ | 519 // Given the |prerender_contents|, find the iterator in active_prerenders_ |
| 604 // correponding to the given prerender. | 520 // correponding to the given prerender. |
| 605 ScopedVector<PrerenderData>::iterator | 521 ScopedVector<PrerenderData>::iterator |
| 606 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents); | 522 FindIteratorForPrerenderContents(PrerenderContents* prerender_contents); |
| 607 | 523 |
| 608 bool DoesRateLimitAllowPrerender(Origin origin) const; | 524 bool DoesRateLimitAllowPrerender(Origin origin) const; |
| 609 | 525 |
| 610 // Deletes old WebContents that have been replaced by prerendered ones. This | 526 // Deletes old WebContents that have been replaced by prerendered ones. This |
| 611 // is needed because they're replaced in a callback from the old WebContents, | 527 // is needed because they're replaced in a callback from the old WebContents, |
| 612 // so cannot immediately be deleted. | 528 // so cannot immediately be deleted. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 void RecordFinalStatusWithoutCreatingPrerenderContents( | 561 void RecordFinalStatusWithoutCreatingPrerenderContents( |
| 646 const GURL& url, Origin origin, uint8 experiment_id, | 562 const GURL& url, Origin origin, uint8 experiment_id, |
| 647 FinalStatus final_status) const; | 563 FinalStatus final_status) const; |
| 648 | 564 |
| 649 | 565 |
| 650 void CookieChanged(ChromeCookieDetails* details); | 566 void CookieChanged(ChromeCookieDetails* details); |
| 651 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key, | 567 void CookieChangedAnyCookiesLeftLookupResult(const std::string& domain_key, |
| 652 bool cookies_exist); | 568 bool cookies_exist); |
| 653 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map); | 569 void LoggedInPredictorDataReceived(scoped_ptr<LoggedInStateMap> new_map); |
| 654 | 570 |
| 655 void RecordEvent(PrerenderContents* contents, PrerenderEvent event) const; | |
| 656 | |
| 657 // Swaps a prerender |prerender_data| for |url| into the tab, replacing | 571 // Swaps a prerender |prerender_data| for |url| into the tab, replacing |
| 658 // |web_contents|. Returns the new WebContents that was swapped in, or NULL | 572 // |web_contents|. Returns the new WebContents that was swapped in, or NULL |
| 659 // if a swap-in was not possible. If |should_replace_current_entry| is true, | 573 // if a swap-in was not possible. If |should_replace_current_entry| is true, |
| 660 // the current history entry in |web_contents| is replaced. | 574 // the current history entry in |web_contents| is replaced. |
| 661 content::WebContents* SwapInternal(const GURL& url, | 575 content::WebContents* SwapInternal(const GURL& url, |
| 662 content::WebContents* web_contents, | 576 content::WebContents* web_contents, |
| 663 PrerenderData* prerender_data, | 577 PrerenderData* prerender_data, |
| 664 bool should_replace_current_entry); | 578 bool should_replace_current_entry); |
| 665 | 579 |
| 666 // The configuration. | 580 // The configuration. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 bool cookie_store_loaded_; | 649 bool cookie_store_loaded_; |
| 736 | 650 |
| 737 base::Closure on_cookie_store_loaded_cb_for_testing_; | 651 base::Closure on_cookie_store_loaded_cb_for_testing_; |
| 738 | 652 |
| 739 DISALLOW_COPY_AND_ASSIGN(PrerenderManager); | 653 DISALLOW_COPY_AND_ASSIGN(PrerenderManager); |
| 740 }; | 654 }; |
| 741 | 655 |
| 742 } // namespace prerender | 656 } // namespace prerender |
| 743 | 657 |
| 744 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ | 658 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_MANAGER_H_ |
| OLD | NEW |