Home | History | Annotate | Download | only in prerender
      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