OLD | NEW |
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 <string> | 7 #include <string> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/field_trial.h" | 10 #include "base/metrics/field_trial.h" |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 const GURL& referrer) { | 215 const GURL& referrer) { |
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
217 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); | 217 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); |
218 if (!prerender_manager || !prerender_manager->is_enabled()) | 218 if (!prerender_manager || !prerender_manager->is_enabled()) |
219 return; | 219 return; |
220 prerender_manager->RecordTagObserved(); | 220 prerender_manager->RecordTagObserved(); |
221 | 221 |
222 std::pair<int, int> child_route_id_pair = std::make_pair(render_process_id, | 222 std::pair<int, int> child_route_id_pair = std::make_pair(render_process_id, |
223 render_view_id); | 223 render_view_id); |
224 | 224 |
225 prerender_manager->AddPreload(child_route_id_pair, url, referrer); | 225 prerender_manager->AddPrerender(child_route_id_pair, url, referrer); |
226 } | 226 } |
227 | 227 |
228 void DestroyPreloadForRenderView( | 228 void DestroyPrerenderForRenderView( |
229 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, | 229 const base::WeakPtr<PrerenderManager>& prerender_manager_weak_ptr, |
230 int render_process_id, | 230 int render_process_id, |
231 int render_view_id, | 231 int render_view_id, |
232 FinalStatus final_status) { | 232 FinalStatus final_status) { |
233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
234 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); | 234 PrerenderManager* prerender_manager = prerender_manager_weak_ptr.get(); |
235 if (!prerender_manager) | 235 if (!prerender_manager) |
236 return; | 236 return; |
237 | 237 |
238 prerender_manager->DestroyPreloadForChildRouteIdPair( | 238 prerender_manager->DestroyPrerenderForChildRouteIdPair( |
239 std::make_pair(render_process_id, render_view_id), | 239 std::make_pair(render_process_id, render_view_id), |
240 final_status); | 240 final_status); |
241 } | 241 } |
242 | 242 |
243 PrerenderManager::PrerenderManager(Profile* profile, | 243 PrerenderManager::PrerenderManager(Profile* profile, |
244 PrerenderTracker* prerender_tracker) | 244 PrerenderTracker* prerender_tracker) |
245 : rate_limit_enabled_(true), | 245 : rate_limit_enabled_(true), |
246 enabled_(true), | 246 enabled_(true), |
247 profile_(profile), | 247 profile_(profile), |
248 prerender_tracker_(prerender_tracker), | 248 prerender_tracker_(prerender_tracker), |
(...skipping 20 matching lines...) Expand all Loading... |
269 } | 269 } |
270 DeletePendingDeleteEntries(); | 270 DeletePendingDeleteEntries(); |
271 } | 271 } |
272 | 272 |
273 void PrerenderManager::SetPrerenderContentsFactory( | 273 void PrerenderManager::SetPrerenderContentsFactory( |
274 PrerenderContents::Factory* prerender_contents_factory) { | 274 PrerenderContents::Factory* prerender_contents_factory) { |
275 DCHECK(CalledOnValidThread()); | 275 DCHECK(CalledOnValidThread()); |
276 prerender_contents_factory_.reset(prerender_contents_factory); | 276 prerender_contents_factory_.reset(prerender_contents_factory); |
277 } | 277 } |
278 | 278 |
279 bool PrerenderManager::AddPreload( | 279 bool PrerenderManager::AddPrerender( |
280 const std::pair<int, int>& child_route_id_pair, | 280 const std::pair<int, int>& child_route_id_pair, |
281 const GURL& url_arg, | 281 const GURL& url_arg, |
282 const GURL& referrer) { | 282 const GURL& referrer) { |
283 DCHECK(CalledOnValidThread()); | 283 DCHECK(CalledOnValidThread()); |
284 | 284 |
285 // If the referring page is prerendering, defer the prerender. | 285 // If the referring page is prerendering, defer the prerender. |
286 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != | 286 if (FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != |
287 prerender_list_.end()) { | 287 prerender_list_.end()) { |
288 AddPendingPreload(child_route_id_pair, url_arg, referrer); | 288 AddPendingPrerender(child_route_id_pair, url_arg, referrer); |
289 return true; | 289 return true; |
290 } | 290 } |
291 | 291 |
292 DeleteOldEntries(); | 292 DeleteOldEntries(); |
293 DeletePendingDeleteEntries(); | 293 DeletePendingDeleteEntries(); |
294 | 294 |
295 GURL url = url_arg; | 295 GURL url = url_arg; |
296 GURL alias_url; | 296 GURL alias_url; |
297 if (IsControlGroup() && | 297 if (IsControlGroup() && |
298 PrerenderManager::MaybeGetQueryStringBasedAliasURL( | 298 PrerenderManager::MaybeGetQueryStringBasedAliasURL( |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 } | 357 } |
358 while (prerender_list_.size() > max_elements_) { | 358 while (prerender_list_.size() > max_elements_) { |
359 data = prerender_list_.front(); | 359 data = prerender_list_.front(); |
360 prerender_list_.pop_front(); | 360 prerender_list_.pop_front(); |
361 data.contents_->Destroy(FINAL_STATUS_EVICTED); | 361 data.contents_->Destroy(FINAL_STATUS_EVICTED); |
362 } | 362 } |
363 StartSchedulingPeriodicCleanups(); | 363 StartSchedulingPeriodicCleanups(); |
364 return true; | 364 return true; |
365 } | 365 } |
366 | 366 |
367 void PrerenderManager::AddPendingPreload( | 367 bool PrerenderManager::AddPrerenderWithNoTag(const GURL& url) { |
| 368 return AddPrerender(std::make_pair(-1, -1), url, GURL()); |
| 369 } |
| 370 |
| 371 void PrerenderManager::AddPendingPrerender( |
368 const std::pair<int, int>& child_route_id_pair, | 372 const std::pair<int, int>& child_route_id_pair, |
369 const GURL& url, | 373 const GURL& url, |
370 const GURL& referrer) { | 374 const GURL& referrer) { |
371 DCHECK(FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != | 375 DCHECK(FindPrerenderContentsForChildRouteIdPair(child_route_id_pair) != |
372 prerender_list_.end()); | 376 prerender_list_.end()); |
373 PendingPrerenderList::iterator it = | 377 PendingPrerenderList::iterator it = |
374 pending_prerender_list_.find(child_route_id_pair); | 378 pending_prerender_list_.find(child_route_id_pair); |
375 if (it == pending_prerender_list_.end()) { | 379 if (it == pending_prerender_list_.end()) { |
376 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair, | 380 PendingPrerenderList::value_type el = std::make_pair(child_route_id_pair, |
377 std::vector<PendingContentsData>()); | 381 std::vector<PendingContentsData>()); |
(...skipping 18 matching lines...) Expand all Loading... |
396 | 400 |
397 if (has_child_id && has_route_id && | 401 if (has_child_id && has_route_id && |
398 child_id == child_route_id_pair.first && | 402 child_id == child_route_id_pair.first && |
399 route_id == child_route_id_pair.second) { | 403 route_id == child_route_id_pair.second) { |
400 break; | 404 break; |
401 } | 405 } |
402 } | 406 } |
403 return it; | 407 return it; |
404 } | 408 } |
405 | 409 |
406 void PrerenderManager::DestroyPreloadForChildRouteIdPair( | 410 void PrerenderManager::DestroyPrerenderForChildRouteIdPair( |
407 const std::pair<int, int>& child_route_id_pair, | 411 const std::pair<int, int>& child_route_id_pair, |
408 FinalStatus final_status) { | 412 FinalStatus final_status) { |
409 DCHECK(CalledOnValidThread()); | 413 DCHECK(CalledOnValidThread()); |
410 std::list<PrerenderContentsData>::iterator it = | 414 std::list<PrerenderContentsData>::iterator it = |
411 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair); | 415 FindPrerenderContentsForChildRouteIdPair(child_route_id_pair); |
412 if (it != prerender_list_.end()) { | 416 if (it != prerender_list_.end()) { |
413 PrerenderContents* prerender_contents = it->contents_; | 417 PrerenderContents* prerender_contents = it->contents_; |
414 prerender_contents->Destroy(final_status); | 418 prerender_contents->Destroy(final_status); |
415 } | 419 } |
416 } | 420 } |
(...skipping 29 matching lines...) Expand all Loading... |
446 } | 450 } |
447 } | 451 } |
448 // Entry not found. | 452 // Entry not found. |
449 return NULL; | 453 return NULL; |
450 } | 454 } |
451 | 455 |
452 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { | 456 PrerenderContents* PrerenderManager::GetEntry(const GURL& url) { |
453 return GetEntryButNotSpecifiedTC(url, NULL); | 457 return GetEntryButNotSpecifiedTC(url, NULL); |
454 } | 458 } |
455 | 459 |
456 bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents, | 460 bool PrerenderManager::MaybeUsePrerenderedPage(TabContents* tab_contents, |
457 const GURL& url, | 461 const GURL& url, |
458 bool has_opener_set) { | 462 bool has_opener_set) { |
459 DCHECK(CalledOnValidThread()); | 463 DCHECK(CalledOnValidThread()); |
460 scoped_ptr<PrerenderContents> prerender_contents( | 464 scoped_ptr<PrerenderContents> prerender_contents( |
461 GetEntryButNotSpecifiedTC(url, tab_contents)); | 465 GetEntryButNotSpecifiedTC(url, tab_contents)); |
462 if (prerender_contents.get() == NULL) | 466 if (prerender_contents.get() == NULL) |
463 return false; | 467 return false; |
464 | 468 |
465 // Do not use the prerendered version if the opener window.property was | 469 // Do not use the prerendered version if the opener window.property was |
466 // supposed to be set. | 470 // supposed to be set. |
467 if (has_opener_set) { | 471 if (has_opener_set) { |
468 prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER); | 472 prerender_contents.release()->Destroy(FINAL_STATUS_WINDOW_OPENER); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 | 557 |
554 // See if we have any pending prerender requests for this routing id and start | 558 // See if we have any pending prerender requests for this routing id and start |
555 // the preload if we do. | 559 // the preload if we do. |
556 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); | 560 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); |
557 PendingPrerenderList::iterator pending_it = | 561 PendingPrerenderList::iterator pending_it = |
558 pending_prerender_list_.find(child_route_pair); | 562 pending_prerender_list_.find(child_route_pair); |
559 if (pending_it != pending_prerender_list_.end()) { | 563 if (pending_it != pending_prerender_list_.end()) { |
560 for (std::vector<PendingContentsData>::iterator content_it = | 564 for (std::vector<PendingContentsData>::iterator content_it = |
561 pending_it->second.begin(); | 565 pending_it->second.begin(); |
562 content_it != pending_it->second.end(); ++content_it) { | 566 content_it != pending_it->second.end(); ++content_it) { |
563 AddPreload(pending_it->first, content_it->url_, content_it->referrer_); | 567 AddPrerender(pending_it->first, content_it->url_, content_it->referrer_); |
564 } | 568 } |
565 pending_prerender_list_.erase(pending_it); | 569 pending_prerender_list_.erase(pending_it); |
566 } | 570 } |
567 | 571 |
568 if (old_tab_contents->tab_contents()->NeedToFireBeforeUnload()) { | 572 if (old_tab_contents->tab_contents()->NeedToFireBeforeUnload()) { |
569 // Schedule the delete to occur after the tab has run its unload handlers. | 573 // Schedule the delete to occur after the tab has run its unload handlers. |
570 on_close_tab_contents_deleters_.push_back( | 574 on_close_tab_contents_deleters_.push_back( |
571 new OnCloseTabContentsDeleter(this, old_tab_contents)); | 575 new OnCloseTabContentsDeleter(this, old_tab_contents)); |
572 old_tab_contents->render_view_host()->FirePageBeforeUnload(false); | 576 old_tab_contents->render_view_host()->FirePageBeforeUnload(false); |
573 } else { | 577 } else { |
574 // No unload handler to run, so delete asap. | 578 // No unload handler to run, so delete asap. |
575 ScheduleDeleteOldTabContents(old_tab_contents, NULL); | 579 ScheduleDeleteOldTabContents(old_tab_contents, NULL); |
576 } | 580 } |
577 return true; | 581 return true; |
578 } | 582 } |
579 | 583 |
580 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { | 584 void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { |
581 DCHECK(CalledOnValidThread()); | 585 DCHECK(CalledOnValidThread()); |
582 DCHECK(!IsPendingDelete(entry)); | 586 DCHECK(!IsPendingDelete(entry)); |
583 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); | 587 for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); |
584 it != prerender_list_.end(); | 588 it != prerender_list_.end(); |
585 ++it) { | 589 ++it) { |
586 if (it->contents_ == entry) { | 590 if (it->contents_ == entry) { |
587 RemovePendingPreload(entry); | 591 RemovePendingPrerender(entry); |
588 prerender_list_.erase(it); | 592 prerender_list_.erase(it); |
589 break; | 593 break; |
590 } | 594 } |
591 } | 595 } |
592 pending_delete_list_.push_back(entry); | 596 pending_delete_list_.push_back(entry); |
593 | 597 |
594 // Destroy the old TabContents relatively promptly to reduce resource usage, | 598 // Destroy the old TabContents relatively promptly to reduce resource usage, |
595 // and in the case of HTML5 media, reduce the change of playing any sound. | 599 // and in the case of HTML5 media, reduce the change of playing any sound. |
596 PostCleanupTask(); | 600 PostCleanupTask(); |
597 } | 601 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 | 764 |
761 void PrerenderManager::RecordTagObserved() { | 765 void PrerenderManager::RecordTagObserved() { |
762 DCHECK(CalledOnValidThread()); | 766 DCHECK(CalledOnValidThread()); |
763 | 767 |
764 // If we observe multiple tags within the 30 second window, we will still | 768 // If we observe multiple tags within the 30 second window, we will still |
765 // reset the window to begin at the most recent occurrence, so that we will | 769 // reset the window to begin at the most recent occurrence, so that we will |
766 // always be in a window in the 30 seconds from each occurrence. | 770 // always be in a window in the 30 seconds from each occurrence. |
767 last_prerender_seen_time_ = base::TimeTicks::Now(); | 771 last_prerender_seen_time_ = base::TimeTicks::Now(); |
768 } | 772 } |
769 | 773 |
770 void PrerenderManager::RemovePendingPreload(PrerenderContents* entry) { | 774 void PrerenderManager::RemovePendingPrerender(PrerenderContents* entry) { |
771 DCHECK(CalledOnValidThread()); | 775 DCHECK(CalledOnValidThread()); |
772 int child_id; | 776 int child_id; |
773 int route_id; | 777 int route_id; |
774 bool has_child_id = entry->GetChildId(&child_id); | 778 bool has_child_id = entry->GetChildId(&child_id); |
775 bool has_route_id = has_child_id && entry->GetRouteId(&route_id); | 779 bool has_route_id = has_child_id && entry->GetRouteId(&route_id); |
776 | 780 |
777 // If the entry doesn't have a RenderViewHost then it didn't start | 781 // If the entry doesn't have a RenderViewHost then it didn't start |
778 // prerendering and there shouldn't be any pending preloads to remove. | 782 // prerendering and there shouldn't be any pending preloads to remove. |
779 if (has_child_id && has_route_id) { | 783 if (has_child_id && has_route_id) { |
780 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); | 784 std::pair<int, int> child_route_pair = std::make_pair(child_id, route_id); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 ScopedVector<OnCloseTabContentsDeleter>::iterator i = std::find( | 981 ScopedVector<OnCloseTabContentsDeleter>::iterator i = std::find( |
978 on_close_tab_contents_deleters_.begin(), | 982 on_close_tab_contents_deleters_.begin(), |
979 on_close_tab_contents_deleters_.end(), | 983 on_close_tab_contents_deleters_.end(), |
980 deleter); | 984 deleter); |
981 DCHECK(i != on_close_tab_contents_deleters_.end()); | 985 DCHECK(i != on_close_tab_contents_deleters_.end()); |
982 on_close_tab_contents_deleters_.erase(i); | 986 on_close_tab_contents_deleters_.erase(i); |
983 } | 987 } |
984 } | 988 } |
985 | 989 |
986 } // namespace prerender | 990 } // namespace prerender |
OLD | NEW |