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