Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: chrome/browser/prerender/prerender_manager.cc

Issue 6625066: Add pending preloads indexed by routing id. Start preloading once we navigate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Windows build fix Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prerender/prerender_manager.h" 5 #include "chrome/browser/prerender/prerender_manager.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 46
47 struct PrerenderManager::PrerenderContentsData { 47 struct PrerenderManager::PrerenderContentsData {
48 PrerenderContents* contents_; 48 PrerenderContents* contents_;
49 base::Time start_time_; 49 base::Time start_time_;
50 PrerenderContentsData(PrerenderContents* contents, base::Time start_time) 50 PrerenderContentsData(PrerenderContents* contents, base::Time start_time)
51 : contents_(contents), 51 : contents_(contents),
52 start_time_(start_time) { 52 start_time_(start_time) {
53 } 53 }
54 }; 54 };
55 55
56 struct PrerenderManager::PendingContentsData {
57 PendingContentsData(const GURL& url, const std::vector<GURL>& alias_urls,
58 const GURL& referrer)
59 : url_(url), alias_urls_(alias_urls), referrer_(referrer) { }
60 ~PendingContentsData() {}
61 GURL url_;
62 std::vector<GURL> alias_urls_;
63 GURL referrer_;
64 };
65
66
56 PrerenderManager::PrerenderManager(Profile* profile) 67 PrerenderManager::PrerenderManager(Profile* profile)
57 : profile_(profile), 68 : profile_(profile),
58 max_prerender_age_(base::TimeDelta::FromSeconds( 69 max_prerender_age_(base::TimeDelta::FromSeconds(
59 kDefaultMaxPrerenderAgeSeconds)), 70 kDefaultMaxPrerenderAgeSeconds)),
60 max_elements_(kDefaultMaxPrerenderElements), 71 max_elements_(kDefaultMaxPrerenderElements),
61 prerender_contents_factory_(PrerenderContents::CreateFactory()) { 72 prerender_contents_factory_(PrerenderContents::CreateFactory()) {
62 } 73 }
63 74
64 PrerenderManager::~PrerenderManager() { 75 PrerenderManager::~PrerenderManager() {
65 while (!prerender_list_.empty()) { 76 while (!prerender_list_.empty()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 while (prerender_list_.size() > max_elements_) { 111 while (prerender_list_.size() > max_elements_) {
101 data = prerender_list_.front(); 112 data = prerender_list_.front();
102 prerender_list_.pop_front(); 113 prerender_list_.pop_front();
103 data.contents_->set_final_status(FINAL_STATUS_EVICTED); 114 data.contents_->set_final_status(FINAL_STATUS_EVICTED);
104 delete data.contents_; 115 delete data.contents_;
105 } 116 }
106 StartSchedulingPeriodicCleanups(); 117 StartSchedulingPeriodicCleanups();
107 return true; 118 return true;
108 } 119 }
109 120
121 void PrerenderManager::AddPendingPreload(
122 const std::pair<int,int>& child_route_id_pair,
123 const GURL& url,
124 const std::vector<GURL>& alias_urls,
125 const GURL& referrer) {
126 PendingPrerenderList::iterator it =
cbentzel 2011/03/16 01:23:28 Should this do FindPendingEntry(url) and early ret
127 pending_prerender_list_.find(child_route_id_pair);
128 if (it == pending_prerender_list_.end()) {
129 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair,
130 std::vector<PendingContentsData>());
131 it = pending_prerender_list_.insert(el).first;
132 }
133
134 it->second.push_back(PendingContentsData(url, alias_urls, referrer));
135 }
136
110 void PrerenderManager::DeleteOldEntries() { 137 void PrerenderManager::DeleteOldEntries() {
111 while (!prerender_list_.empty()) { 138 while (!prerender_list_.empty()) {
112 PrerenderContentsData data = prerender_list_.front(); 139 PrerenderContentsData data = prerender_list_.front();
113 if (IsPrerenderElementFresh(data.start_time_)) 140 if (IsPrerenderElementFresh(data.start_time_))
114 return; 141 return;
115 prerender_list_.pop_front(); 142 prerender_list_.pop_front();
116 data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT); 143 data.contents_->set_final_status(FINAL_STATUS_TIMED_OUT);
117 delete data.contents_; 144 delete data.contents_;
118 } 145 }
119 if (prerender_list_.empty()) 146 if (prerender_list_.empty())
(...skipping 28 matching lines...) Expand all
148 175
149 RenderViewHost* rvh = pc->render_view_host(); 176 RenderViewHost* rvh = pc->render_view_host();
150 // RenderViewHosts in PrerenderContents start out hidden. 177 // RenderViewHosts in PrerenderContents start out hidden.
151 // Since we are actually using it now, restore it. 178 // Since we are actually using it now, restore it.
152 rvh->WasRestored(); 179 rvh->WasRestored();
153 pc->set_render_view_host(NULL); 180 pc->set_render_view_host(NULL);
154 rvh->Send(new ViewMsg_DisplayPrerenderedPage(rvh->routing_id())); 181 rvh->Send(new ViewMsg_DisplayPrerenderedPage(rvh->routing_id()));
155 tc->SwapInRenderViewHost(rvh); 182 tc->SwapInRenderViewHost(rvh);
156 MarkTabContentsAsPrerendered(tc); 183 MarkTabContentsAsPrerendered(tc);
157 184
185 // See if we have any pending prerender requests for this routing id and start
186 // the preload if we do.
187 std::pair<int, int> child_route_pair = std::make_pair(rvh->process()->id(),
188 rvh->routing_id());
189 PendingPrerenderList::iterator pending_it =
190 pending_prerender_list_.find(child_route_pair);
191 if (pending_it != pending_prerender_list_.end()) {
192 for (std::vector<PendingContentsData>::iterator content_it =
193 pending_it->second.begin();
194 content_it != pending_it->second.end(); ++content_it) {
195 AddPreload(content_it->url_, content_it->alias_urls_,
196 content_it->referrer_);
197 }
198 pending_prerender_list_.erase(pending_it);
199 }
200
158 ViewHostMsg_FrameNavigate_Params* p = pc->navigate_params(); 201 ViewHostMsg_FrameNavigate_Params* p = pc->navigate_params();
159 if (p != NULL) 202 if (p != NULL)
160 tc->DidNavigate(rvh, *p); 203 tc->DidNavigate(rvh, *p);
161 204
162 string16 title = pc->title(); 205 string16 title = pc->title();
163 if (!title.empty()) 206 if (!title.empty())
164 tc->UpdateTitle(rvh, pc->page_id(), UTF16ToWideHack(title)); 207 tc->UpdateTitle(rvh, pc->page_id(), UTF16ToWideHack(title));
165 208
166 GURL icon_url = pc->icon_url(); 209 GURL icon_url = pc->icon_url();
167 if (!icon_url.is_empty()) 210 if (!icon_url.is_empty())
168 tc->fav_icon_helper().OnUpdateFavIconURL(pc->page_id(), icon_url); 211 tc->fav_icon_helper().OnUpdateFavIconURL(pc->page_id(), icon_url);
169 212
170 if (pc->has_stopped_loading()) 213 if (pc->has_stopped_loading())
171 tc->DidStopLoading(); 214 tc->DidStopLoading();
172 215
173 return true; 216 return true;
174 } 217 }
175 218
176 void PrerenderManager::RemoveEntry(PrerenderContents* entry) { 219 void PrerenderManager::RemoveEntry(PrerenderContents* entry) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
178 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); 221 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin();
179 it != prerender_list_.end(); 222 it != prerender_list_.end();
180 ++it) { 223 ++it) {
181 if (it->contents_ == entry) { 224 if (it->contents_ == entry) {
225 RemovePendingPreload(entry);
182 prerender_list_.erase(it); 226 prerender_list_.erase(it);
183 break; 227 break;
184 } 228 }
185 } 229 }
186 DeleteOldEntries(); 230 DeleteOldEntries();
187 } 231 }
188 232
189 base::Time PrerenderManager::GetCurrentTime() const { 233 base::Time PrerenderManager::GetCurrentTime() const {
190 return base::Time::Now(); 234 return base::Time::Now();
191 } 235 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); 278 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin();
235 it != prerender_list_.end(); 279 it != prerender_list_.end();
236 ++it) { 280 ++it) {
237 if (it->contents_->MatchesURL(url)) 281 if (it->contents_->MatchesURL(url))
238 return it->contents_; 282 return it->contents_;
239 } 283 }
240 // Entry not found. 284 // Entry not found.
241 return NULL; 285 return NULL;
242 } 286 }
243 287
288 PrerenderManager::PendingContentsData*
289 PrerenderManager::FindPendingEntry(const GURL& url) {
cbentzel 2011/03/16 01:23:28 This should be const [I noticed FindEntry wasn't,
290 for (PendingPrerenderList::iterator map_it = pending_prerender_list_.begin();
291 map_it != pending_prerender_list_.end();
292 ++map_it) {
293 for (std::vector<PendingContentsData>::iterator content_it =
294 map_it->second.begin();
295 content_it != map_it->second.end();
296 ++content_it) {
297 if (content_it->url_ == url)
cbentzel 2011/03/16 01:23:28 This will probably want to match against alias url
298 return &(*content_it);
299 }
300 }
301
302 return NULL;
303 }
304
244 // static 305 // static
245 void PrerenderManager::RecordPrefetchTagObserved() { 306 void PrerenderManager::RecordPrefetchTagObserved() {
246 // Ensure that we are in the UI thread, and post to the UI thread if 307 // Ensure that we are in the UI thread, and post to the UI thread if
247 // necessary. 308 // necessary.
248 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 309 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
249 BrowserThread::PostTask( 310 BrowserThread::PostTask(
250 BrowserThread::UI, 311 BrowserThread::UI,
251 FROM_HERE, 312 FROM_HERE,
252 NewRunnableFunction( 313 NewRunnableFunction(
253 &PrerenderManager::RecordPrefetchTagObservedOnUIThread)); 314 &PrerenderManager::RecordPrefetchTagObservedOnUIThread));
254 } else { 315 } else {
255 RecordPrefetchTagObservedOnUIThread(); 316 RecordPrefetchTagObservedOnUIThread();
256 } 317 }
257 } 318 }
258 319
259 // static 320 // static
260 void PrerenderManager::RecordPrefetchTagObservedOnUIThread() { 321 void PrerenderManager::RecordPrefetchTagObservedOnUIThread() {
261 // Once we get here, we have to be on the UI thread. 322 // Once we get here, we have to be on the UI thread.
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
263 324
264 // If we observe multiple tags within the 30 second window, we will still 325 // If we observe multiple tags within the 30 second window, we will still
265 // reset the window to begin at the most recent occurrence, so that we will 326 // reset the window to begin at the most recent occurrence, so that we will
266 // always be in a window in the 30 seconds from each occurrence. 327 // always be in a window in the 30 seconds from each occurrence.
267 last_prefetch_seen_time_ = base::TimeTicks::Now(); 328 last_prefetch_seen_time_ = base::TimeTicks::Now();
268 } 329 }
269 330
331 void PrerenderManager::RemovePendingPreload(PrerenderContents* entry) {
332 RenderViewHost* rvh = entry->render_view_host();
333
334 // If the entry doesn't have a RenderViewHost then it didn't start
335 // prerendering and there shouldn't be any pending preloads to remove.
336 if (rvh == NULL)
337 return;
338
339 std::pair<int, int> child_route_pair = std::make_pair(rvh->process()->id(),
340 rvh->routing_id());
341 pending_prerender_list_.erase(child_route_pair);
342 }
343
270 // static 344 // static
271 bool PrerenderManager::ShouldRecordWindowedPPLT() { 345 bool PrerenderManager::ShouldRecordWindowedPPLT() {
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
273 if (last_prefetch_seen_time_.is_null()) 347 if (last_prefetch_seen_time_.is_null())
274 return false; 348 return false;
275 base::TimeDelta elapsed_time = 349 base::TimeDelta elapsed_time =
276 base::TimeTicks::Now() - last_prefetch_seen_time_; 350 base::TimeTicks::Now() - last_prefetch_seen_time_;
277 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowedPPLTSeconds); 351 return elapsed_time <= base::TimeDelta::FromSeconds(kWindowedPPLTSeconds);
278 } 352 }
279 353
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 388
315 void PrerenderManager::MarkTabContentsAsNotPrerendered(TabContents* tc) { 389 void PrerenderManager::MarkTabContentsAsNotPrerendered(TabContents* tc) {
316 prerendered_tc_set_.erase(tc); 390 prerendered_tc_set_.erase(tc);
317 } 391 }
318 392
319 bool PrerenderManager::IsTabContentsPrerendered(TabContents* tc) const { 393 bool PrerenderManager::IsTabContentsPrerendered(TabContents* tc) const {
320 return prerendered_tc_set_.count(tc) > 0; 394 return prerendered_tc_set_.count(tc) > 0;
321 } 395 }
322 396
323 } // namespace prerender 397 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698