| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 if (!source_web_contents) | 338 if (!source_web_contents) |
| 339 return NULL; | 339 return NULL; |
| 340 if (source_web_contents->GetURL().host() == url.host()) | 340 if (source_web_contents->GetURL().host() == url.host()) |
| 341 origin = ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN; | 341 origin = ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN; |
| 342 // TODO(ajwong): This does not correctly handle storage for isolated apps. | 342 // TODO(ajwong): This does not correctly handle storage for isolated apps. |
| 343 session_storage_namespace = | 343 session_storage_namespace = |
| 344 source_web_contents->GetController() | 344 source_web_contents->GetController() |
| 345 .GetDefaultSessionStorageNamespace(); | 345 .GetDefaultSessionStorageNamespace(); |
| 346 } | 346 } |
| 347 | 347 |
| 348 // If the prerender request comes from a recently cancelled prerender that | |
| 349 // |this| still owns, then abort the prerender. | |
| 350 for (ScopedVector<PrerenderData>::iterator it = to_delete_prerenders_.begin(); | |
| 351 it != to_delete_prerenders_.end(); ++it) { | |
| 352 PrerenderContents* prerender_contents = (*it)->contents(); | |
| 353 int contents_child_id; | |
| 354 int contents_route_id; | |
| 355 if (prerender_contents->GetChildId(&contents_child_id) && | |
| 356 prerender_contents->GetRouteId(&contents_route_id)) { | |
| 357 if (contents_child_id == process_id && contents_route_id == route_id) | |
| 358 return NULL; | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 if (PrerenderData* parent_prerender_data = | |
| 363 FindPrerenderDataForChildAndRoute(process_id, route_id)) { | |
| 364 // Instead of prerendering from inside of a running prerender, we will defer | |
| 365 // this request until its launcher is made visible. | |
| 366 if (PrerenderContents* contents = parent_prerender_data->contents()) { | |
| 367 PrerenderHandle* prerender_handle = | |
| 368 new PrerenderHandle(static_cast<PrerenderData*>(NULL)); | |
| 369 scoped_ptr<PrerenderContents::PendingPrerenderInfo> | |
| 370 pending_prerender_info(new PrerenderContents::PendingPrerenderInfo( | |
| 371 prerender_handle->weak_ptr_factory_.GetWeakPtr(), | |
| 372 origin, url, referrer, size)); | |
| 373 | |
| 374 contents->AddPendingPrerender(pending_prerender_info.Pass()); | |
| 375 return prerender_handle; | |
| 376 } | |
| 377 } | |
| 378 | |
| 379 return AddPrerender(origin, process_id, url, referrer, size, | 348 return AddPrerender(origin, process_id, url, referrer, size, |
| 380 session_storage_namespace); | 349 session_storage_namespace); |
| 381 } | 350 } |
| 382 | 351 |
| 383 PrerenderHandle* PrerenderManager::AddPrerenderFromOmnibox( | 352 PrerenderHandle* PrerenderManager::AddPrerenderFromOmnibox( |
| 384 const GURL& url, | 353 const GURL& url, |
| 385 SessionStorageNamespace* session_storage_namespace, | 354 SessionStorageNamespace* session_storage_namespace, |
| 386 const gfx::Size& size) { | 355 const gfx::Size& size) { |
| 387 if (!IsOmniboxEnabled(profile_)) | 356 if (!IsOmniboxEnabled(profile_)) |
| 388 return NULL; | 357 return NULL; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 | 552 |
| 584 // For bookkeeping purposes, we need to mark this WebContents to | 553 // For bookkeeping purposes, we need to mark this WebContents to |
| 585 // reflect that it would have been prerendered. | 554 // reflect that it would have been prerendered. |
| 586 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { | 555 if (GetMode() == PRERENDER_MODE_EXPERIMENT_NO_USE_GROUP) { |
| 587 MarkWebContentsAsWouldBePrerendered(web_contents, | 556 MarkWebContentsAsWouldBePrerendered(web_contents, |
| 588 prerender_data->contents()->origin()); | 557 prerender_data->contents()->origin()); |
| 589 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); | 558 prerender_data->contents()->Destroy(FINAL_STATUS_WOULD_HAVE_BEEN_USED); |
| 590 return NULL; | 559 return NULL; |
| 591 } | 560 } |
| 592 | 561 |
| 593 int child_id, route_id; | |
| 594 CHECK(prerender_data->contents()->GetChildId(&child_id)); | |
| 595 CHECK(prerender_data->contents()->GetRouteId(&route_id)); | |
| 596 | |
| 597 // At this point, we've determined that we will use the prerender. | 562 // At this point, we've determined that we will use the prerender. |
| 598 if (prerender_data->pending_swap()) | 563 if (prerender_data->pending_swap()) |
| 599 prerender_data->pending_swap()->set_swap_successful(true); | 564 prerender_data->pending_swap()->set_swap_successful(true); |
| 600 ScopedVector<PrerenderData>::iterator to_erase = | 565 ScopedVector<PrerenderData>::iterator to_erase = |
| 601 FindIteratorForPrerenderContents(prerender_data->contents()); | 566 FindIteratorForPrerenderContents(prerender_data->contents()); |
| 602 DCHECK(active_prerenders_.end() != to_erase); | 567 DCHECK(active_prerenders_.end() != to_erase); |
| 603 DCHECK_EQ(prerender_data, *to_erase); | 568 DCHECK_EQ(prerender_data, *to_erase); |
| 604 scoped_ptr<PrerenderContents> | 569 scoped_ptr<PrerenderContents> |
| 605 prerender_contents(prerender_data->ReleaseContents()); | 570 prerender_contents(prerender_data->ReleaseContents()); |
| 606 active_prerenders_.erase(to_erase); | 571 active_prerenders_.erase(to_erase); |
| 607 | 572 |
| 608 if (!prerender_contents->load_start_time().is_null()) { | 573 if (!prerender_contents->load_start_time().is_null()) { |
| 609 histograms_->RecordTimeUntilUsed( | 574 histograms_->RecordTimeUntilUsed( |
| 610 prerender_contents->origin(), | 575 prerender_contents->origin(), |
| 611 GetCurrentTimeTicks() - prerender_contents->load_start_time()); | 576 GetCurrentTimeTicks() - prerender_contents->load_start_time()); |
| 612 } | 577 } |
| 613 | 578 |
| 614 histograms_->RecordPerSessionCount(prerender_contents->origin(), | 579 histograms_->RecordPerSessionCount(prerender_contents->origin(), |
| 615 ++prerenders_per_session_count_); | 580 ++prerenders_per_session_count_); |
| 616 histograms_->RecordUsedPrerender(prerender_contents->origin()); | 581 histograms_->RecordUsedPrerender(prerender_contents->origin()); |
| 617 prerender_contents->SetFinalStatus(FINAL_STATUS_USED); | |
| 618 | 582 |
| 619 // Start pending prerender requests from the PrerenderContents, if there are | 583 // Mark prerender as used. |
| 620 // any. | |
| 621 prerender_contents->PrepareForUse(); | 584 prerender_contents->PrepareForUse(); |
| 622 | 585 |
| 623 WebContents* new_web_contents = | 586 WebContents* new_web_contents = |
| 624 prerender_contents->ReleasePrerenderContents(); | 587 prerender_contents->ReleasePrerenderContents(); |
| 625 WebContents* old_web_contents = web_contents; | 588 WebContents* old_web_contents = web_contents; |
| 626 DCHECK(new_web_contents); | 589 DCHECK(new_web_contents); |
| 627 DCHECK(old_web_contents); | 590 DCHECK(old_web_contents); |
| 628 | 591 |
| 629 MarkWebContentsAsPrerendered(new_web_contents, prerender_contents->origin()); | 592 MarkWebContentsAsPrerendered(new_web_contents, prerender_contents->origin()); |
| 630 | 593 |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); | 1245 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); |
| 1283 prerender_data_->ClearPendingSwap(); | 1246 prerender_data_->ClearPendingSwap(); |
| 1284 } | 1247 } |
| 1285 | 1248 |
| 1286 void PrerenderManager::SetPrerenderContentsFactory( | 1249 void PrerenderManager::SetPrerenderContentsFactory( |
| 1287 PrerenderContents::Factory* prerender_contents_factory) { | 1250 PrerenderContents::Factory* prerender_contents_factory) { |
| 1288 DCHECK(CalledOnValidThread()); | 1251 DCHECK(CalledOnValidThread()); |
| 1289 prerender_contents_factory_.reset(prerender_contents_factory); | 1252 prerender_contents_factory_.reset(prerender_contents_factory); |
| 1290 } | 1253 } |
| 1291 | 1254 |
| 1292 | |
| 1293 void PrerenderManager::StartPendingPrerenders( | |
| 1294 const int process_id, | |
| 1295 ScopedVector<PrerenderContents::PendingPrerenderInfo>* pending_prerenders, | |
| 1296 content::SessionStorageNamespace* session_storage_namespace) { | |
| 1297 for (ScopedVector<PrerenderContents::PendingPrerenderInfo>::iterator | |
| 1298 it = pending_prerenders->begin(); | |
| 1299 it != pending_prerenders->end(); ++it) { | |
| 1300 PrerenderContents::PendingPrerenderInfo* info = *it; | |
| 1301 PrerenderHandle* existing_prerender_handle = | |
| 1302 info->weak_prerender_handle.get(); | |
| 1303 if (!existing_prerender_handle) | |
| 1304 continue; | |
| 1305 | |
| 1306 DCHECK(!existing_prerender_handle->IsPrerendering()); | |
| 1307 DCHECK(process_id == -1 || session_storage_namespace); | |
| 1308 | |
| 1309 scoped_ptr<PrerenderHandle> new_prerender_handle(AddPrerender( | |
| 1310 info->origin, process_id, | |
| 1311 info->url, info->referrer, info->size, | |
| 1312 session_storage_namespace)); | |
| 1313 if (new_prerender_handle) { | |
| 1314 // AddPrerender has returned a new prerender handle to us. We want to make | |
| 1315 // |existing_prerender_handle| active, so move the underlying | |
| 1316 // PrerenderData to our new handle. | |
| 1317 existing_prerender_handle->AdoptPrerenderDataFrom( | |
| 1318 new_prerender_handle.get()); | |
| 1319 continue; | |
| 1320 } | |
| 1321 } | |
| 1322 } | |
| 1323 | |
| 1324 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { | 1255 void PrerenderManager::SourceNavigatedAway(PrerenderData* prerender_data) { |
| 1325 // The expiry time of our prerender data will likely change because of | 1256 // The expiry time of our prerender data will likely change because of |
| 1326 // this navigation. This requires a resort of active_prerenders_. | 1257 // this navigation. This requires a resort of active_prerenders_. |
| 1327 ScopedVector<PrerenderData>::iterator it = | 1258 ScopedVector<PrerenderData>::iterator it = |
| 1328 std::find(active_prerenders_.begin(), active_prerenders_.end(), | 1259 std::find(active_prerenders_.begin(), active_prerenders_.end(), |
| 1329 prerender_data); | 1260 prerender_data); |
| 1330 if (it == active_prerenders_.end()) | 1261 if (it == active_prerenders_.end()) |
| 1331 return; | 1262 return; |
| 1332 | 1263 |
| 1333 (*it)->set_expiry_time( | 1264 (*it)->set_expiry_time( |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 const GURL& url, | 1496 const GURL& url, |
| 1566 const SessionStorageNamespace* session_storage_namespace) { | 1497 const SessionStorageNamespace* session_storage_namespace) { |
| 1567 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | 1498 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); |
| 1568 it != active_prerenders_.end(); ++it) { | 1499 it != active_prerenders_.end(); ++it) { |
| 1569 if ((*it)->contents()->Matches(url, session_storage_namespace)) | 1500 if ((*it)->contents()->Matches(url, session_storage_namespace)) |
| 1570 return *it; | 1501 return *it; |
| 1571 } | 1502 } |
| 1572 return NULL; | 1503 return NULL; |
| 1573 } | 1504 } |
| 1574 | 1505 |
| 1575 PrerenderManager::PrerenderData* | |
| 1576 PrerenderManager::FindPrerenderDataForChildAndRoute( | |
| 1577 const int child_id, const int route_id) { | |
| 1578 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | |
| 1579 it != active_prerenders_.end(); ++it) { | |
| 1580 PrerenderContents* prerender_contents = (*it)->contents(); | |
| 1581 | |
| 1582 int contents_child_id; | |
| 1583 if (!prerender_contents->GetChildId(&contents_child_id)) | |
| 1584 continue; | |
| 1585 int contents_route_id; | |
| 1586 if (!prerender_contents->GetRouteId(&contents_route_id)) | |
| 1587 continue; | |
| 1588 | |
| 1589 if (contents_child_id == child_id && contents_route_id == route_id) | |
| 1590 return *it; | |
| 1591 } | |
| 1592 return NULL; | |
| 1593 } | |
| 1594 | |
| 1595 ScopedVector<PrerenderManager::PrerenderData>::iterator | 1506 ScopedVector<PrerenderManager::PrerenderData>::iterator |
| 1596 PrerenderManager::FindIteratorForPrerenderContents( | 1507 PrerenderManager::FindIteratorForPrerenderContents( |
| 1597 PrerenderContents* prerender_contents) { | 1508 PrerenderContents* prerender_contents) { |
| 1598 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); | 1509 for (ScopedVector<PrerenderData>::iterator it = active_prerenders_.begin(); |
| 1599 it != active_prerenders_.end(); ++it) { | 1510 it != active_prerenders_.end(); ++it) { |
| 1600 if (prerender_contents == (*it)->contents()) | 1511 if (prerender_contents == (*it)->contents()) |
| 1601 return it; | 1512 return it; |
| 1602 } | 1513 } |
| 1603 return active_prerenders_.end(); | 1514 return active_prerenders_.end(); |
| 1604 } | 1515 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 Origin origin, | 1830 Origin origin, |
| 1920 uint8 experiment_id, | 1831 uint8 experiment_id, |
| 1921 CancelableRequestProvider::Handle handle, | 1832 CancelableRequestProvider::Handle handle, |
| 1922 bool success, | 1833 bool success, |
| 1923 const history::URLRow* url_row, | 1834 const history::URLRow* url_row, |
| 1924 history::VisitVector* visists) { | 1835 history::VisitVector* visists) { |
| 1925 histograms_->RecordPrerenderPageVisitedStatus(origin, experiment_id, success); | 1836 histograms_->RecordPrerenderPageVisitedStatus(origin, experiment_id, success); |
| 1926 } | 1837 } |
| 1927 | 1838 |
| 1928 } // namespace prerender | 1839 } // namespace prerender |
| OLD | NEW |