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_TRACKER_H_ 6 #define CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_ 7 8 #include <map> 9 #include <set> 10 #include <utility> 11 #include <vector> 12 13 #include "base/gtest_prod_util.h" 14 #include "base/synchronization/lock.h" 15 #include "base/threading/non_thread_safe.h" 16 #include "chrome/browser/prerender/prerender_contents.h" 17 #include "chrome/browser/prerender/prerender_final_status.h" 18 #include "url/gurl.h" 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. 28 class PrerenderTracker : public base::NonThreadSafe, 29 public PrerenderContents::Observer { 30 public: 31 PrerenderTracker(); 32 virtual ~PrerenderTracker(); 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 36 // already been cancelled for any reason or is no longer prerendering. 37 // Can only be called only on the IO thread. This method will not call 38 // PrerenderContents::SetFinalStatus() on the corresponding PrerenderContents. 39 // 40 // If it returns true, all subsequent calls to TryCancel and TryUse for the 41 // RenderView will return false. 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 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 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 71 private: 72 friend class PrerenderContents; 73 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerNull); 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 80 typedef std::pair<int, int> ChildRouteIdPair; 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 86 // From PrerenderContents::Observer: 87 virtual void OnPrerenderStart(PrerenderContents* prerender_contents) OVERRIDE; 88 virtual void OnPrerenderStop(PrerenderContents* prerender_contents) OVERRIDE; 89 90 // Attempts to set the FinalStatus of the specified RenderView to 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); 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 117 static PrerenderTracker* GetDefault(); 118 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 131 DISALLOW_COPY_AND_ASSIGN(PrerenderTracker); 132 }; 133 134 } // namespace prerender 135 136 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_ 137