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.
5 #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_
6 #define CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/non_thread_safe.h"
17 #include "chrome/browser/prerender/prerender_contents.h"
18 #include "chrome/browser/prerender/prerender_final_status.h"
23 class PrerenderManager;
24 class PrerenderResourceThrottle;
25 struct RenderViewInfo;
27 // PrerenderTracker is responsible for keeping track of all prerendering
28 // RenderViews and their statuses. Its list is guaranteed to be up to date
29 // and can be modified on any thread.
30 class PrerenderTracker : public base::NonThreadSafe,
31 public PrerenderContents::Observer {
34 virtual ~PrerenderTracker();
36 // Attempts to set the status of the specified RenderViewHost to
37 // FINAL_STATUS_USED. Returns true on success. Returns false if it has
38 // already been cancelled for any reason or is no longer prerendering.
39 // Can only be called only on the UI thread. This method will not call
40 // PrerenderContents::SetFinalStatus() on the corresponding PrerenderContents.
42 // If it returns true, all subsequent calls to TryCancel and TryUse for the
43 // RenderView will return false.
44 bool TryUse(int child_id, int route_id);
46 // Attempts to cancel prerendering by the specified RenderView, setting the
47 // FinalStatus to |final_status|. Returns true if the specified prerender has
48 // been cancelled, either as a result of this call or for any other reason.
49 // If the call results in cancelling a PrerenderContents, a task to destroy
50 // it is also posted to the UI thread.
52 // When true is returned, it is guaranteed that the RenderView will never
53 // be displayed. When false is returned, the RenderView has either been
54 // swapped into a tab or has already been destroyed.
55 bool TryCancel(int child_id, int route_id, FinalStatus final_status);
57 // Same as above, but can only called on the IO Thread. Does not acquire a
58 // lock when the RenderView is not being prerendered.
59 bool TryCancelOnIOThread(int child_id, int route_id,
60 FinalStatus final_status);
62 // Gets the FinalStatus of the specified prerendered RenderView. Returns
63 // |true| and sets |final_status| to the status of the RenderView if it
64 // is found, returns false otherwise.
65 bool GetFinalStatus(int child_id, int route_id,
66 FinalStatus* final_status) const;
68 // Returns whether or not a RenderView is prerendering. Can only be called on
69 // the IO thread. Does not acquire a lock, so may claim a RenderView that has
70 // been displayed or destroyed is still prerendering.
71 bool IsPrerenderingOnIOThread(int child_id, int route_id) const;
73 // Called when a PrerenderResourceThrottle defers a request. Cancel
74 // or Resume will be called on |throttle| when the prerender is
75 // canceled or used, respectively.
76 void AddResourceThrottleOnIOThread(
77 int child_id, int route_id,
78 const base::WeakPtr<PrerenderResourceThrottle>& throttle);
81 friend class PrerenderContents;
82 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerNull);
83 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerUsed);
84 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelled);
85 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelledOnIO);
86 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerCancelledFast);
87 FRIEND_TEST_ALL_PREFIXES(PrerenderTrackerTest, PrerenderTrackerMultiple);
89 typedef std::pair<int, int> ChildRouteIdPair;
90 // Map of child/route id pairs to final statuses.
91 typedef std::map<ChildRouteIdPair, RenderViewInfo> FinalStatusMap;
92 // List of throttled requests.
93 typedef std::vector<base::WeakPtr<PrerenderResourceThrottle> >
95 // Set of throttled requests.
96 typedef std::map<ChildRouteIdPair, ResourceThrottleList> ResourceThrottleMap;
98 // From PrerenderContents::Observer:
99 virtual void OnPrerenderStart(PrerenderContents* prerender_contents) OVERRIDE;
100 virtual void OnPrerenderStop(PrerenderContents* prerender_contents) OVERRIDE;
102 // Attempts to set the FinalStatus of the specified RenderView to
103 // |desired_final_status|. If non-NULL, |actual_final_status| is set to the
104 // FinalStatus of the RenderView.
106 // If the FinalStatus of the RenderView is successfully set, returns true and
107 // sets |actual_final_status| to |desired_final_status|.
109 // If the FinalStatus of the RenderView was already set, returns false and
110 // sets |actual_final_status| to the actual FinalStatus of the RenderView.
112 // If the RenderView is not a prerendering RenderView, returns false and sets
113 // |actual_final_status| to FINAL_STATUS_MAX.
114 bool SetFinalStatus(int child_id, int route_id,
115 FinalStatus desired_final_status,
116 FinalStatus* actual_final_status);
118 // Add/remove the specified pair to |possibly_prerendering_io_thread_set_| on
120 void AddPrerenderOnIOThread(const ChildRouteIdPair& child_route_id_pair);
121 void RemovePrerenderOnIOThread(const ChildRouteIdPair& child_route_id_pair,
122 FinalStatus final_status);
124 // Tasks posted to the IO Thread to call the above functions.
125 static void AddPrerenderOnIOThreadTask(
126 const ChildRouteIdPair& child_route_id_pair);
127 static void RemovePrerenderOnIOThreadTask(
128 const ChildRouteIdPair& child_route_id_pair,
129 FinalStatus final_status);
131 static PrerenderTracker* GetDefault();
133 // |final_status_map_lock_| protects access to |final_status_map_|.
134 mutable base::Lock final_status_map_lock_;
135 // Map containing child/route id pairs and their final statuses. Must only be
136 // accessed while the lock is held. Values are always accurate and up to
138 FinalStatusMap final_status_map_;
140 // Resources that are throttled, pending a prerender use. The keys are a
141 // superset of child/route id pairs that are prerendering. Can only access on
142 // the IO thread. May contain entries that have since been displayed. Used
143 // to prevent locking when not needed.
144 ResourceThrottleMap resource_throttle_io_thread_map_;
146 DISALLOW_COPY_AND_ASSIGN(PrerenderTracker);
149 } // namespace prerender
151 #endif // CHROME_BROWSER_PRERENDER_PRERENDER_TRACKER_H_