| 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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 if (prerender_namespace && prerender_namespace != target_namespace && | 487 if (prerender_namespace && prerender_namespace != target_namespace && |
| 488 !prerender_namespace->IsAliasOf(target_namespace)) { | 488 !prerender_namespace->IsAliasOf(target_namespace)) { |
| 489 if (!ShouldMergeSessionStorageNamespaces()) { | 489 if (!ShouldMergeSessionStorageNamespaces()) { |
| 490 RecordEvent(prerender_data->contents(), | 490 RecordEvent(prerender_data->contents(), |
| 491 PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); | 491 PRERENDER_EVENT_SWAPIN_MERGING_DISABLED); |
| 492 return false; | 492 return false; |
| 493 } | 493 } |
| 494 RecordEvent(prerender_data->contents(), | 494 RecordEvent(prerender_data->contents(), |
| 495 PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); | 495 PRERENDER_EVENT_SWAPIN_ISSUING_MERGE); |
| 496 prerender_data->set_pending_swap(new PendingSwap( | 496 prerender_data->set_pending_swap(new PendingSwap( |
| 497 this, web_contents, prerender_data, url)); | 497 this, web_contents, prerender_data, url, |
| 498 params->should_replace_current_entry)); |
| 498 prerender_data->pending_swap()->BeginSwap(); | 499 prerender_data->pending_swap()->BeginSwap(); |
| 499 // Although this returns false, creating a PendingSwap registers with | 500 // Although this returns false, creating a PendingSwap registers with |
| 500 // PrerenderTracker to throttle MAIN_FRAME navigations while the swap is | 501 // PrerenderTracker to throttle MAIN_FRAME navigations while the swap is |
| 501 // pending. | 502 // pending. |
| 502 return false; | 503 return false; |
| 503 } | 504 } |
| 504 | 505 |
| 505 // No need to merge; swap synchronously. | 506 // No need to merge; swap synchronously. |
| 506 WebContents* new_web_contents = SwapInternal(url, web_contents, | 507 WebContents* new_web_contents = SwapInternal( |
| 507 prerender_data); | 508 url, web_contents, prerender_data, |
| 509 params->should_replace_current_entry); |
| 508 if (!new_web_contents) | 510 if (!new_web_contents) |
| 509 return false; | 511 return false; |
| 510 | 512 |
| 511 // Record the new target_contents for the callers. | 513 // Record the new target_contents for the callers. |
| 512 params->target_contents = new_web_contents; | 514 params->target_contents = new_web_contents; |
| 513 return true; | 515 return true; |
| 514 } | 516 } |
| 515 | 517 |
| 516 WebContents* PrerenderManager::SwapInternal( | 518 WebContents* PrerenderManager::SwapInternal( |
| 517 const GURL& url, | 519 const GURL& url, |
| 518 WebContents* web_contents, | 520 WebContents* web_contents, |
| 519 PrerenderData* prerender_data) { | 521 PrerenderData* prerender_data, |
| 522 bool should_replace_current_entry) { |
| 520 DCHECK(CalledOnValidThread()); | 523 DCHECK(CalledOnValidThread()); |
| 521 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); | 524 DCHECK(!IsWebContentsPrerendering(web_contents, NULL)); |
| 522 | 525 |
| 523 // Only swap if the target WebContents has a CoreTabHelper delegate to swap | 526 // Only swap if the target WebContents has a CoreTabHelper delegate to swap |
| 524 // out of it. For a normal WebContents, this is if it is in a TabStripModel. | 527 // out of it. For a normal WebContents, this is if it is in a TabStripModel. |
| 525 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); | 528 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(web_contents); |
| 526 if (!core_tab_helper || !core_tab_helper->delegate()) { | 529 if (!core_tab_helper || !core_tab_helper->delegate()) { |
| 527 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_NO_DELEGATE); | 530 RecordEvent(prerender_data->contents(), PRERENDER_EVENT_SWAPIN_NO_DELEGATE); |
| 528 return NULL; | 531 return NULL; |
| 529 } | 532 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 WebContents* new_web_contents = | 644 WebContents* new_web_contents = |
| 642 prerender_contents->ReleasePrerenderContents(); | 645 prerender_contents->ReleasePrerenderContents(); |
| 643 WebContents* old_web_contents = web_contents; | 646 WebContents* old_web_contents = web_contents; |
| 644 DCHECK(new_web_contents); | 647 DCHECK(new_web_contents); |
| 645 DCHECK(old_web_contents); | 648 DCHECK(old_web_contents); |
| 646 | 649 |
| 647 MarkWebContentsAsPrerendered(new_web_contents, prerender_contents->origin()); | 650 MarkWebContentsAsPrerendered(new_web_contents, prerender_contents->origin()); |
| 648 | 651 |
| 649 // Merge the browsing history. | 652 // Merge the browsing history. |
| 650 new_web_contents->GetController().CopyStateFromAndPrune( | 653 new_web_contents->GetController().CopyStateFromAndPrune( |
| 651 &old_web_contents->GetController()); | 654 &old_web_contents->GetController(), |
| 655 should_replace_current_entry); |
| 652 CoreTabHelper::FromWebContents(old_web_contents)->delegate()-> | 656 CoreTabHelper::FromWebContents(old_web_contents)->delegate()-> |
| 653 SwapTabContents(old_web_contents, new_web_contents); | 657 SwapTabContents(old_web_contents, new_web_contents); |
| 654 prerender_contents->CommitHistory(new_web_contents); | 658 prerender_contents->CommitHistory(new_web_contents); |
| 655 | 659 |
| 656 GURL icon_url = prerender_contents->icon_url(); | 660 GURL icon_url = prerender_contents->icon_url(); |
| 657 | 661 |
| 658 if (!icon_url.is_empty()) { | 662 if (!icon_url.is_empty()) { |
| 659 #if defined(OS_ANDROID) | 663 #if defined(OS_ANDROID) |
| 660 // Do the delayed icon fetch since we didn't download | 664 // Do the delayed icon fetch since we didn't download |
| 661 // the favicon during prerendering on mobile devices. | 665 // the favicon during prerendering on mobile devices. |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 } | 1155 } |
| 1152 | 1156 |
| 1153 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { | 1157 PrerenderContents* PrerenderManager::PrerenderData::ReleaseContents() { |
| 1154 return contents_.release(); | 1158 return contents_.release(); |
| 1155 } | 1159 } |
| 1156 | 1160 |
| 1157 PrerenderManager::PendingSwap::PendingSwap( | 1161 PrerenderManager::PendingSwap::PendingSwap( |
| 1158 PrerenderManager* manager, | 1162 PrerenderManager* manager, |
| 1159 content::WebContents* target_contents, | 1163 content::WebContents* target_contents, |
| 1160 PrerenderData* prerender_data, | 1164 PrerenderData* prerender_data, |
| 1161 const GURL& url) | 1165 const GURL& url, |
| 1166 bool should_replace_current_entry) |
| 1162 : content::WebContentsObserver(target_contents), | 1167 : content::WebContentsObserver(target_contents), |
| 1163 manager_(manager), | 1168 manager_(manager), |
| 1164 target_contents_(target_contents), | 1169 target_contents_(target_contents), |
| 1165 prerender_data_(prerender_data), | 1170 prerender_data_(prerender_data), |
| 1166 url_(url), | 1171 url_(url), |
| 1172 should_replace_current_entry_(should_replace_current_entry), |
| 1167 start_time_(base::TimeTicks::Now()), | 1173 start_time_(base::TimeTicks::Now()), |
| 1168 swap_successful_(false), | 1174 swap_successful_(false), |
| 1169 weak_factory_(this) { | 1175 weak_factory_(this) { |
| 1170 RenderViewCreated(target_contents->GetRenderViewHost()); | 1176 RenderViewCreated(target_contents->GetRenderViewHost()); |
| 1171 } | 1177 } |
| 1172 | 1178 |
| 1173 PrerenderManager::PendingSwap::~PendingSwap() { | 1179 PrerenderManager::PendingSwap::~PendingSwap() { |
| 1174 for (size_t i = 0; i < rvh_ids_.size(); i++) { | 1180 for (size_t i = 0; i < rvh_ids_.size(); i++) { |
| 1175 manager_->prerender_tracker()->RemovePrerenderPendingSwap( | 1181 manager_->prerender_tracker()->RemovePrerenderPendingSwap( |
| 1176 rvh_ids_[i], swap_successful_); | 1182 rvh_ids_[i], swap_successful_); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 return; | 1299 return; |
| 1294 } | 1300 } |
| 1295 | 1301 |
| 1296 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); | 1302 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPPING_IN); |
| 1297 // Note that SwapInternal, on success, will delete |prerender_data_| and | 1303 // Note that SwapInternal, on success, will delete |prerender_data_| and |
| 1298 // |this|. Pass in a new GURL object rather than a reference to |url_|. | 1304 // |this|. Pass in a new GURL object rather than a reference to |url_|. |
| 1299 // | 1305 // |
| 1300 // TODO(davidben): See about deleting PrerenderData asynchronously so this | 1306 // TODO(davidben): See about deleting PrerenderData asynchronously so this |
| 1301 // behavior is more reasonable. | 1307 // behavior is more reasonable. |
| 1302 WebContents* new_web_contents = | 1308 WebContents* new_web_contents = |
| 1303 manager_->SwapInternal(GURL(url_), target_contents_, prerender_data_); | 1309 manager_->SwapInternal(GURL(url_), target_contents_, prerender_data_, |
| 1310 should_replace_current_entry_); |
| 1304 if (!new_web_contents) { | 1311 if (!new_web_contents) { |
| 1305 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); | 1312 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_SWAPIN_FAILED); |
| 1306 prerender_data_->ClearPendingSwap(); | 1313 prerender_data_->ClearPendingSwap(); |
| 1307 } | 1314 } |
| 1308 } | 1315 } |
| 1309 | 1316 |
| 1310 void PrerenderManager::PendingSwap::OnMergeTimeout() { | 1317 void PrerenderManager::PendingSwap::OnMergeTimeout() { |
| 1311 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); | 1318 RecordEvent(PRERENDER_EVENT_MERGE_RESULT_TIMED_OUT); |
| 1312 prerender_data_->ClearPendingSwap(); | 1319 prerender_data_->ClearPendingSwap(); |
| 1313 } | 1320 } |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1880 void PrerenderManager::RecordEvent(PrerenderContents* contents, | 1887 void PrerenderManager::RecordEvent(PrerenderContents* contents, |
| 1881 PrerenderEvent event) const { | 1888 PrerenderEvent event) const { |
| 1882 if (!contents) | 1889 if (!contents) |
| 1883 histograms_->RecordEvent(ORIGIN_NONE, kNoExperiment, event); | 1890 histograms_->RecordEvent(ORIGIN_NONE, kNoExperiment, event); |
| 1884 else | 1891 else |
| 1885 histograms_->RecordEvent(contents->origin(), contents->experiment_id(), | 1892 histograms_->RecordEvent(contents->origin(), contents->experiment_id(), |
| 1886 event); | 1893 event); |
| 1887 } | 1894 } |
| 1888 | 1895 |
| 1889 } // namespace prerender | 1896 } // namespace prerender |
| OLD | NEW |