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 |