| 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 |