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 |