| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <functional> | 10 #include <functional> |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 #include "content/public/browser/render_frame_host.h" | 58 #include "content/public/browser/render_frame_host.h" |
| 59 #include "content/public/browser/render_process_host.h" | 59 #include "content/public/browser/render_process_host.h" |
| 60 #include "content/public/browser/render_view_host.h" | 60 #include "content/public/browser/render_view_host.h" |
| 61 #include "content/public/browser/resource_request_details.h" | 61 #include "content/public/browser/resource_request_details.h" |
| 62 #include "content/public/browser/session_storage_namespace.h" | 62 #include "content/public/browser/session_storage_namespace.h" |
| 63 #include "content/public/browser/site_instance.h" | 63 #include "content/public/browser/site_instance.h" |
| 64 #include "content/public/browser/web_contents.h" | 64 #include "content/public/browser/web_contents.h" |
| 65 #include "content/public/browser/web_contents_delegate.h" | 65 #include "content/public/browser/web_contents_delegate.h" |
| 66 #include "content/public/common/url_constants.h" | 66 #include "content/public/common/url_constants.h" |
| 67 #include "extensions/common/constants.h" | 67 #include "extensions/common/constants.h" |
| 68 #include "net/http/http_cache.h" |
| 68 #include "net/http/http_request_headers.h" | 69 #include "net/http/http_request_headers.h" |
| 69 #include "ui/gfx/geometry/rect.h" | 70 #include "ui/gfx/geometry/rect.h" |
| 70 | 71 |
| 71 using chrome_browser_net::NetworkPredictionStatus; | 72 using chrome_browser_net::NetworkPredictionStatus; |
| 72 using content::BrowserThread; | 73 using content::BrowserThread; |
| 73 using content::RenderViewHost; | 74 using content::RenderViewHost; |
| 74 using content::SessionStorageNamespace; | 75 using content::SessionStorageNamespace; |
| 75 using content::WebContents; | 76 using content::WebContents; |
| 76 | 77 |
| 77 namespace prerender { | 78 namespace prerender { |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 redirect_count); | 569 redirect_count); |
| 569 } | 570 } |
| 570 | 571 |
| 571 void PrerenderManager::RecordNoStateFirstContentfulPaint(const GURL& url, | 572 void PrerenderManager::RecordNoStateFirstContentfulPaint(const GURL& url, |
| 572 bool is_no_store, | 573 bool is_no_store, |
| 573 bool was_hidden, | 574 bool was_hidden, |
| 574 base::TimeDelta time) { | 575 base::TimeDelta time) { |
| 575 base::TimeDelta prefetch_age; | 576 base::TimeDelta prefetch_age; |
| 576 Origin origin; | 577 Origin origin; |
| 577 GetPrefetchInformation(url, &prefetch_age, &origin); | 578 GetPrefetchInformation(url, &prefetch_age, &origin); |
| 579 OnPrefetchUsed(url); |
| 578 | 580 |
| 579 histograms_->RecordPrefetchFirstContentfulPaintTime( | 581 histograms_->RecordPrefetchFirstContentfulPaintTime( |
| 580 origin, is_no_store, was_hidden, time, prefetch_age); | 582 origin, is_no_store, was_hidden, time, prefetch_age); |
| 581 | 583 |
| 582 for (auto& observer : observers_) { | 584 for (auto& observer : observers_) { |
| 583 observer->OnFirstContentfulPaint(); | 585 observer->OnFirstContentfulPaint(); |
| 584 } | 586 } |
| 585 } | 587 } |
| 586 | 588 |
| 587 void PrerenderManager::RecordPrerenderFirstContentfulPaint( | 589 void PrerenderManager::RecordPrerenderFirstContentfulPaint( |
| 588 const GURL& url, | 590 const GURL& url, |
| 589 content::WebContents* web_contents, | 591 content::WebContents* web_contents, |
| 590 bool is_no_store, | 592 bool is_no_store, |
| 591 bool was_hidden, | 593 bool was_hidden, |
| 592 base::TimeTicks first_contentful_paint) { | 594 base::TimeTicks first_contentful_paint) { |
| 593 DCHECK(!first_contentful_paint.is_null()); | 595 DCHECK(!first_contentful_paint.is_null()); |
| 594 | 596 |
| 595 PrerenderTabHelper* tab_helper = | 597 PrerenderTabHelper* tab_helper = |
| 596 PrerenderTabHelper::FromWebContents(web_contents); | 598 PrerenderTabHelper::FromWebContents(web_contents); |
| 597 DCHECK(tab_helper); | 599 DCHECK(tab_helper); |
| 598 | 600 |
| 599 base::TimeDelta prefetch_age; | 601 base::TimeDelta prefetch_age; |
| 600 // The origin at prefetch is superceeded by the tab_helper origin for the | 602 // The origin at prefetch is superceeded by the tab_helper origin for the |
| 601 // histogram recording, below. | 603 // histogram recording, below. |
| 602 Origin unused_origin; | 604 GetPrefetchInformation(url, &prefetch_age, nullptr); |
| 603 GetPrefetchInformation(url, &prefetch_age, &unused_origin); | 605 OnPrefetchUsed(url); |
| 604 | 606 |
| 605 base::TimeTicks swap_ticks = tab_helper->swap_ticks(); | 607 base::TimeTicks swap_ticks = tab_helper->swap_ticks(); |
| 606 bool fcp_recorded = false; | 608 bool fcp_recorded = false; |
| 607 if (!swap_ticks.is_null() && !first_contentful_paint.is_null()) { | 609 if (!swap_ticks.is_null() && !first_contentful_paint.is_null()) { |
| 608 histograms_->RecordPrefetchFirstContentfulPaintTime( | 610 histograms_->RecordPrefetchFirstContentfulPaintTime( |
| 609 tab_helper->origin(), is_no_store, was_hidden, | 611 tab_helper->origin(), is_no_store, was_hidden, |
| 610 first_contentful_paint - swap_ticks, prefetch_age); | 612 first_contentful_paint - swap_ticks, prefetch_age); |
| 611 fcp_recorded = true; | 613 fcp_recorded = true; |
| 612 } | 614 } |
| 613 histograms_->RecordPerceivedFirstContentfulPaintStatus( | 615 histograms_->RecordPerceivedFirstContentfulPaintStatus( |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 if (prerendering_status != NetworkPredictionStatus::ENABLED) { | 934 if (prerendering_status != NetworkPredictionStatus::ENABLED) { |
| 933 FinalStatus final_status = | 935 FinalStatus final_status = |
| 934 prerendering_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK | 936 prerendering_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK |
| 935 ? FINAL_STATUS_CELLULAR_NETWORK | 937 ? FINAL_STATUS_CELLULAR_NETWORK |
| 936 : FINAL_STATUS_PRERENDERING_DISABLED; | 938 : FINAL_STATUS_PRERENDERING_DISABLED; |
| 937 RecordFinalStatusWithoutCreatingPrerenderContents(url, origin, | 939 RecordFinalStatusWithoutCreatingPrerenderContents(url, origin, |
| 938 final_status); | 940 final_status); |
| 939 return nullptr; | 941 return nullptr; |
| 940 } | 942 } |
| 941 | 943 |
| 942 if (PrerenderData* preexisting_prerender_data = | 944 if (IsNoStatePrefetch(origin)) { |
| 943 FindPrerenderData(url, session_storage_namespace)) { | 945 base::TimeDelta prefetch_age; |
| 946 GetPrefetchInformation(url, &prefetch_age, nullptr); |
| 947 if (!prefetch_age.is_zero() && |
| 948 prefetch_age < |
| 949 base::TimeDelta::FromMinutes(net::HttpCache::kPrefetchReuseMins)) { |
| 950 RecordFinalStatusWithoutCreatingPrerenderContents(url, origin, |
| 951 FINAL_STATUS_DUPLICATE); |
| 952 return nullptr; |
| 953 } |
| 954 } else if (PrerenderData* preexisting_prerender_data = |
| 955 FindPrerenderData(url, session_storage_namespace)) { |
| 944 RecordFinalStatusWithoutCreatingPrerenderContents( | 956 RecordFinalStatusWithoutCreatingPrerenderContents( |
| 945 url, origin, FINAL_STATUS_DUPLICATE); | 957 url, origin, FINAL_STATUS_DUPLICATE); |
| 946 return base::WrapUnique(new PrerenderHandle(preexisting_prerender_data)); | 958 return base::WrapUnique(new PrerenderHandle(preexisting_prerender_data)); |
| 947 } | 959 } |
| 948 | 960 |
| 949 // Do not prerender if there are too many render processes, and we would | 961 // Do not prerender if there are too many render processes, and we would |
| 950 // have to use an existing one. We do not want prerendering to happen in | 962 // have to use an existing one. We do not want prerendering to happen in |
| 951 // a shared process, so that we can always reliably lower the CPU | 963 // a shared process, so that we can always reliably lower the CPU |
| 952 // priority for prerendering. | 964 // priority for prerendering. |
| 953 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns | 965 // In single-process mode, ShouldTryToUseExistingProcessHost() always returns |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 // Or should |old_web_contents_list_| contain unique_ptrs? | 1197 // Or should |old_web_contents_list_| contain unique_ptrs? |
| 1186 delete web_contents; | 1198 delete web_contents; |
| 1187 } | 1199 } |
| 1188 old_web_contents_list_.clear(); | 1200 old_web_contents_list_.clear(); |
| 1189 } | 1201 } |
| 1190 | 1202 |
| 1191 void PrerenderManager::GetPrefetchInformation(const GURL& url, | 1203 void PrerenderManager::GetPrefetchInformation(const GURL& url, |
| 1192 base::TimeDelta* prefetch_age, | 1204 base::TimeDelta* prefetch_age, |
| 1193 Origin* origin) { | 1205 Origin* origin) { |
| 1194 DCHECK(prefetch_age); | 1206 DCHECK(prefetch_age); |
| 1195 DCHECK(origin); | |
| 1196 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); | 1207 CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); |
| 1197 | 1208 |
| 1198 *prefetch_age = base::TimeDelta(); | 1209 *prefetch_age = base::TimeDelta(); |
| 1199 *origin = ORIGIN_NONE; | 1210 if (origin) |
| 1211 *origin = ORIGIN_NONE; |
| 1200 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) { | 1212 for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) { |
| 1201 if (it->url == url) { | 1213 if (it->url == url) { |
| 1202 *prefetch_age = GetCurrentTimeTicks() - it->time; | 1214 *prefetch_age = GetCurrentTimeTicks() - it->time; |
| 1203 *origin = it->origin; | 1215 if (origin) |
| 1216 *origin = it->origin; |
| 1204 break; | 1217 break; |
| 1205 } | 1218 } |
| 1206 } | 1219 } |
| 1220 } |
| 1207 | 1221 |
| 1222 void PrerenderManager::OnPrefetchUsed(const GURL& url) { |
| 1208 // Loading a prefetched URL resets the revalidation bypass. Remove all | 1223 // Loading a prefetched URL resets the revalidation bypass. Remove all |
| 1209 // matching urls from the prefetch list for more accurate metrics. | 1224 // matching urls from the prefetch list for more accurate metrics. |
| 1210 prefetches_.erase( | 1225 prefetches_.erase( |
| 1211 std::remove_if(prefetches_.begin(), prefetches_.end(), | 1226 std::remove_if(prefetches_.begin(), prefetches_.end(), |
| 1212 [url](const NavigationRecord& r) { return r.url == url; }), | 1227 [url](const NavigationRecord& r) { return r.url == url; }), |
| 1213 prefetches_.end()); | 1228 prefetches_.end()); |
| 1214 } | 1229 } |
| 1215 | 1230 |
| 1216 void PrerenderManager::CleanUpOldNavigations( | 1231 void PrerenderManager::CleanUpOldNavigations( |
| 1217 std::vector<NavigationRecord>* navigations, | 1232 std::vector<NavigationRecord>* navigations, |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1422 return weak_factory_.GetWeakPtr(); | 1437 return weak_factory_.GetWeakPtr(); |
| 1423 } | 1438 } |
| 1424 | 1439 |
| 1425 void PrerenderManager::SetPrerenderContentsFactoryForTest( | 1440 void PrerenderManager::SetPrerenderContentsFactoryForTest( |
| 1426 PrerenderContents::Factory* prerender_contents_factory) { | 1441 PrerenderContents::Factory* prerender_contents_factory) { |
| 1427 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1442 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1428 prerender_contents_factory_.reset(prerender_contents_factory); | 1443 prerender_contents_factory_.reset(prerender_contents_factory); |
| 1429 } | 1444 } |
| 1430 | 1445 |
| 1431 } // namespace prerender | 1446 } // namespace prerender |
| OLD | NEW |