[email protected] | f4dda482 | 2012-02-17 20:03:07 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 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_TRACKER_H_ |
| 6 | #define CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_ |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 7 | |
| 8 | #include <map> |
| 9 | #include <set> |
[email protected] | ac4f468 | 2012-12-08 22:39:26 | [diff] [blame] | 10 | #include <utility> |
[email protected] | 92e0a61 | 2011-05-30 21:37:00 | [diff] [blame] | 11 | #include <vector> |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 12 | |
[email protected] | 1459fb6 | 2011-05-25 19:03:27 | [diff] [blame] | 13 | #include "base/gtest_prod_util.h" |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 14 | #include "base/synchronization/lock.h" |
[email protected] | 92e0a61 | 2011-05-30 21:37:00 | [diff] [blame] | 15 | #include "base/threading/non_thread_safe.h" |
[email protected] | ac4f468 | 2012-12-08 22:39:26 | [diff] [blame] | 16 | #include "chrome/browser/prerender/prerender_contents.h" |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 17 | #include "chrome/browser/prerender/prerender_final_status.h" |
[email protected] | 92e0a61 | 2011-05-30 21:37:00 | [diff] [blame] | 18 | #include "googleurl/src/gurl.h" |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 19 | |
| 20 | namespace prerender { |
| 21 | |
| 22 | class PrerenderManager; |
| 23 | struct RenderViewInfo; |
| 24 | |
| 25 | // PrerenderTracker is responsible for keeping track of all prerendering |
| 26 | // RenderViews and their statuses. Its list is guaranteed to be up to date |
| 27 | // and can be modified on any thread. |
[email protected] | ac4f468 | 2012-12-08 22:39:26 | [diff] [blame] | 28 | class PrerenderTracker : public base::NonThreadSafe, |
| 29 | public PrerenderContents::Observer { |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 30 | public: |
[email protected] | 1459fb6 | 2011-05-25 19:03:27 | [diff] [blame] | 31 | PrerenderTracker(); |
[email protected] | ac4f468 | 2012-12-08 22:39:26 | [diff] [blame] | 32 | virtual ~PrerenderTracker(); |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 33 | |
| 34 | // Attempts to set the status of the specified RenderViewHost to |
| 35 | // FINAL_STATUS_USED. Returns true on success. Returns false if it has |
[email protected] | 33bb16e | 2011-05-23 21:27:58 | [diff] [blame] | 36 | // already been cancelled for any reason or is no longer prerendering. |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 37 | // Can only be called only on the IO thread. This method will not call |
[email protected] | ac4f468 | 2012-12-08 22:39:26 | [diff] [blame] | 38 | // PrerenderContents::SetFinalStatus() on the corresponding PrerenderContents. |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 39 | // |
[email protected] | 33bb16e | 2011-05-23 21:27:58 | [diff] [blame] | 40 | // If it returns true, all subsequent calls to TryCancel and TryUse for the |
| 41 | // RenderView will return false. |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 42 | bool TryUse(int child_id, int route_id); |
| 43 | |
| 44 | // Attempts to cancel prerendering by the specified RenderView, setting the |
| 45 | // FinalStatus to |final_status|. Returns true if the specified prerender has |
| 46 | // been cancelled, either as a result of this call or for any other reason. |
| 47 | // If the call results in cancelling a PrerenderContents, a task to destroy |
| 48 | // it is also posted to the UI thread. |
| 49 | // |
| 50 | // When true is returned, it is guaranteed that the RenderView will never |
| 51 | // be displayed. When false is returned, the RenderView has either been |
| 52 | // swapped into a tab or has already been destroyed. |
| 53 | bool TryCancel(int child_id, int route_id, FinalStatus final_status); |
| 54 | |
| 55 | // Same as above, but can only called on the IO Thread. Does not acquire a |
| 56 | // lock when the RenderView is not being prerendered. |
| 57 | bool TryCancelOnIOThread(int child_id, int route_id, |
| 58 | FinalStatus final_status); |
| 59 | |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 60 | // Gets the FinalStatus of the specified prerendered RenderView. Returns |
| 61 | // |true| and sets |final_status| to the status of the RenderView if it |
| 62 | // is found, returns false otherwise. |
| 63 | bool GetFinalStatus(int child_id, int route_id, |
| 64 | FinalStatus* final_status) const; |
| 65 | |
[email protected] | 1459fb6 | 2011-05-25 19:03:27 | [diff] [blame] | 66 | // Returns whether or not a RenderView is prerendering. Can only be called on |
| 67 | // the IO thread. Does not acquire a lock, so may claim a RenderView that has |
| 68 | // been displayed or destroyed is still prerendering. |
| 69 | bool IsPrerenderingOnIOThread(int child_id, int route_id) const; |
| 70 | |
[email protected] | 33bb16e | 2011-05-23 21:27:58 | [diff] [blame] | 71 | private: |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 72 | friend class PrerenderContents; |
[email protected] | 1459fb6 | 2011-05-25 19:03:27 | [diff] [blame] | 73 | FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerNull); |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 74 | FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerUsed); |
| 75 | FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelled); |
| 76 | FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelledOnIO); |
| 77 | FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelledFast); |
| 78 | FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerMultiple); |
| 79 | |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 80 | typedef std::pair<int, int> ChildRouteIdPair; |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 81 | // Map of child/route id pairs to final statuses. |
| 82 | typedef std::map<ChildRouteIdPair, RenderViewInfo> FinalStatusMap; |
| 83 | // Set of child/route id pairs that may be prerendering. |
| 84 | typedef std::set<ChildRouteIdPair> PossiblyPrerenderingChildRouteIdPairs; |
| 85 | |
[email protected] | ac4f468 | 2012-12-08 22:39:26 | [diff] [blame] | 86 | // From PrerenderContents::Observer: |
| 87 | virtual void OnPrerenderStart(PrerenderContents* prerender_contents) OVERRIDE; |
| 88 | virtual void OnPrerenderStop(PrerenderContents* prerender_contents) OVERRIDE; |
[email protected] | 33bb16e | 2011-05-23 21:27:58 | [diff] [blame] | 89 | |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 90 | // Attempts to set the FinalStatus of the specified RenderView to |
[email protected] | 33bb16e | 2011-05-23 21:27:58 | [diff] [blame] | 91 | // |desired_final_status|. If non-NULL, |actual_final_status| is set to the |
| 92 | // FinalStatus of the RenderView. |
| 93 | // |
| 94 | // If the FinalStatus of the RenderView is successfully set, returns true and |
| 95 | // sets |actual_final_status| to |desired_final_status|. |
| 96 | // |
| 97 | // If the FinalStatus of the RenderView was already set, returns false and |
| 98 | // sets |actual_final_status| to the actual FinalStatus of the RenderView. |
| 99 | // |
| 100 | // If the RenderView is not a prerendering RenderView, returns false and sets |
| 101 | // |actual_final_status| to FINAL_STATUS_MAX. |
| 102 | bool SetFinalStatus(int child_id, int route_id, |
| 103 | FinalStatus desired_final_status, |
| 104 | FinalStatus* actual_final_status); |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 105 | |
| 106 | // Add/remove the specified pair to |possibly_prerendering_io_thread_set_| on |
| 107 | // the IO Thread. |
| 108 | void AddPrerenderOnIOThread(const ChildRouteIdPair& child_route_id_pair); |
| 109 | void RemovePrerenderOnIOThread(const ChildRouteIdPair& child_route_id_pair); |
| 110 | |
| 111 | // Tasks posted to the IO Thread to call the above functions. |
| 112 | static void AddPrerenderOnIOThreadTask( |
| 113 | const ChildRouteIdPair& child_route_id_pair); |
| 114 | static void RemovePrerenderOnIOThreadTask( |
| 115 | const ChildRouteIdPair& child_route_id_pair); |
| 116 | |
[email protected] | 92e0a61 | 2011-05-30 21:37:00 | [diff] [blame] | 117 | static PrerenderTracker* GetDefault(); |
| 118 | |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 119 | // |final_status_map_lock_| protects access to |final_status_map_|. |
| 120 | mutable base::Lock final_status_map_lock_; |
| 121 | // Map containing child/route id pairs and their final statuses. Must only be |
| 122 | // accessed while the lock is held. Values are always accurate and up to |
| 123 | // date. |
| 124 | FinalStatusMap final_status_map_; |
| 125 | |
| 126 | // Superset of child/route id pairs that are prerendering. Can only access on |
| 127 | // the IO thread. May contain entries that have since been displayed. Only |
| 128 | // used to prevent locking when not needed. |
| 129 | PossiblyPrerenderingChildRouteIdPairs possibly_prerendering_io_thread_set_; |
| 130 | |
[email protected] | 28a05f3a | 2011-05-20 15:05:08 | [diff] [blame] | 131 | DISALLOW_COPY_AND_ASSIGN(PrerenderTracker); |
| 132 | }; |
| 133 | |
| 134 | } // namespace prerender |
| 135 | |
| 136 | #endif // CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_ |