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_LINK_MANAGER_H_
      6 #define CHROME_BROWSER_PRERENDER_PRERENDER_LINK_MANAGER_H_
      7 
      8 #include <list>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/gtest_prod_util.h"
     12 #include "base/time/time.h"
     13 #include "chrome/browser/prerender/prerender_handle.h"
     14 #include "components/keyed_service/core/keyed_service.h"
     15 #include "url/gurl.h"
     16 
     17 class Profile;
     18 
     19 namespace content {
     20 struct Referrer;
     21 }
     22 
     23 namespace gfx {
     24 class Size;
     25 }
     26 
     27 FORWARD_DECLARE_TEST(WebViewTest, NoPrerenderer);
     28 
     29 namespace prerender {
     30 
     31 class PrerenderContents;
     32 class PrerenderManager;
     33 
     34 // PrerenderLinkManager implements the API on Link elements for all documents
     35 // being rendered in this chrome instance.  It receives messages from the
     36 // renderer indicating addition, cancelation and abandonment of link elements,
     37 // and controls the PrerenderManager accordingly.
     38 class PrerenderLinkManager : public KeyedService,
     39                              public PrerenderHandle::Observer {
     40  public:
     41   explicit PrerenderLinkManager(PrerenderManager* manager);
     42   virtual ~PrerenderLinkManager();
     43 
     44   // A <link rel=prerender ...> element has been inserted into the document.
     45   // The |prerender_id| must be unique per |child_id|, and is assigned by the
     46   // WebPrerendererClient.
     47   void OnAddPrerender(int child_id,
     48                       int prerender_id,
     49                       const GURL& url,
     50                       uint32 rel_types,
     51                       const content::Referrer& referrer,
     52                       const gfx::Size& size,
     53                       int render_view_route_id);
     54 
     55   // A <link rel=prerender ...> element has been explicitly removed from a
     56   // document.
     57   void OnCancelPrerender(int child_id, int prerender_id);
     58 
     59   // A renderer launching <link rel=prerender ...> has navigated away from the
     60   // launching page, the launching renderer process has crashed, or perhaps the
     61   // renderer process was fast-closed when the last render view in it was
     62   // closed.
     63   void OnAbandonPrerender(int child_id, int prerender_id);
     64 
     65   // If a renderer channel closes (crash, fast exit, etc...), that's effectively
     66   // an abandon of any prerenders launched by that child.
     67   void OnChannelClosing(int child_id);
     68 
     69  private:
     70   friend class PrerenderBrowserTest;
     71   friend class PrerenderTest;
     72   // WebViewTest.NoPrerenderer needs to access the private IsEmpty() method.
     73   FRIEND_TEST_ALL_PREFIXES(::WebViewTest, NoPrerenderer);
     74 
     75   struct LinkPrerender {
     76     LinkPrerender(int launcher_child_id,
     77                   int prerender_id,
     78                   const GURL& url,
     79                   uint32 rel_types,
     80                   const content::Referrer& referrer,
     81                   const gfx::Size& size,
     82                   int render_view_route_id,
     83                   base::TimeTicks creation_time,
     84                   PrerenderContents* deferred_launcher);
     85     ~LinkPrerender();
     86 
     87     // Parameters from PrerenderLinkManager::OnAddPrerender():
     88     int launcher_child_id;
     89     int prerender_id;
     90     GURL url;
     91     uint32 rel_types;
     92     content::Referrer referrer;
     93     gfx::Size size;
     94     int render_view_route_id;
     95 
     96     // The time at which this Prerender was added to PrerenderLinkManager.
     97     base::TimeTicks creation_time;
     98 
     99     // If non-NULL, this link prerender was launched by an unswapped prerender,
    100     // |deferred_launcher|. When |deferred_launcher| is swapped in, the field is
    101     // set to NULL.
    102     PrerenderContents* deferred_launcher;
    103 
    104     // Initially NULL, |handle| is set once we start this prerender. It is owned
    105     // by this struct, and must be deleted before destructing this struct.
    106     PrerenderHandle* handle;
    107 
    108     // True if this prerender has become a MatchComplete replacement. This state
    109     // is maintained so the renderer is not notified of a stop twice.
    110     bool is_match_complete_replacement;
    111 
    112     // True if this prerender has been abandoned by its launcher.
    113     bool has_been_abandoned;
    114   };
    115 
    116   class PendingPrerenderManager;
    117 
    118   bool IsEmpty() const;
    119 
    120   // Returns a count of currently running prerenders.
    121   size_t CountRunningPrerenders() const;
    122 
    123   // Start any prerenders that can be started, respecting concurrency limits for
    124   // the system and per launcher.
    125   void StartPrerenders();
    126 
    127   LinkPrerender* FindByLauncherChildIdAndPrerenderId(int child_id,
    128                                                      int prerender_id);
    129 
    130   LinkPrerender* FindByPrerenderHandle(PrerenderHandle* prerender_handle);
    131 
    132   // Removes |prerender| from the the prerender link manager. Deletes the
    133   // PrerenderHandle as needed.
    134   void RemovePrerender(LinkPrerender* prerender);
    135 
    136   // Cancels |prerender| and removes |prerender| from the prerender link
    137   // manager.
    138   void CancelPrerender(LinkPrerender* prerender);
    139 
    140   // Called when |launcher| is swapped in.
    141   void StartPendingPrerendersForLauncher(PrerenderContents* launcher);
    142 
    143   // Called when |launcher| is aborted.
    144   void CancelPendingPrerendersForLauncher(PrerenderContents* launcher);
    145 
    146   // From KeyedService:
    147   virtual void Shutdown() OVERRIDE;
    148 
    149   // From PrerenderHandle::Observer:
    150   virtual void OnPrerenderStart(PrerenderHandle* prerender_handle) OVERRIDE;
    151   virtual void OnPrerenderStopLoading(PrerenderHandle* prerender_handle)
    152       OVERRIDE;
    153   virtual void OnPrerenderDomContentLoaded(PrerenderHandle* prerender_handle)
    154       OVERRIDE;
    155   virtual void OnPrerenderStop(PrerenderHandle* prerender_handle) OVERRIDE;
    156   virtual void OnPrerenderCreatedMatchCompleteReplacement(
    157       PrerenderHandle* handle) OVERRIDE;
    158 
    159   bool has_shutdown_;
    160 
    161   PrerenderManager* manager_;
    162 
    163   // All prerenders known to this PrerenderLinkManager. Insertions are always
    164   // made at the back, so the oldest prerender is at the front, and the youngest
    165   // at the back.
    166   std::list<LinkPrerender> prerenders_;
    167 
    168   // Helper object to manage prerenders which are launched by other prerenders
    169   // and must be deferred until the launcher is swapped in.
    170   scoped_ptr<PendingPrerenderManager> pending_prerender_manager_;
    171 
    172   DISALLOW_COPY_AND_ASSIGN(PrerenderLinkManager);
    173 };
    174 
    175 }  // namespace prerender
    176 
    177 #endif  // CHROME_BROWSER_PRERENDER_PRERENDER_LINK_MANAGER_H_
    178