| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/predictors/resource_prefetch_predictor.h" | 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "base/trace_event/trace_event.h" | 16 #include "base/trace_event/trace_event.h" |
| 17 #include "chrome/browser/history/history_service_factory.h" | 17 #include "chrome/browser/history/history_service_factory.h" |
| 18 #include "chrome/browser/predictors/loading_stats_collector.h" | 18 #include "chrome/browser/predictors/loading_stats_collector.h" |
| 19 #include "chrome/browser/predictors/predictor_database.h" | 19 #include "chrome/browser/predictors/predictor_database.h" |
| 20 #include "chrome/browser/predictors/predictor_database_factory.h" | 20 #include "chrome/browser/predictors/predictor_database_factory.h" |
| 21 #include "chrome/browser/predictors/resource_prefetcher_manager.h" | |
| 22 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 23 #include "components/history/core/browser/history_database.h" | 22 #include "components/history/core/browser/history_database.h" |
| 24 #include "components/history/core/browser/history_service.h" | 23 #include "components/history/core/browser/history_service.h" |
| 25 #include "components/history/core/browser/url_utils.h" | 24 #include "components/history/core/browser/url_utils.h" |
| 26 #include "components/mime_util/mime_util.h" | 25 #include "components/mime_util/mime_util.h" |
| 27 #include "components/precache/core/precache_manifest_util.h" | 26 #include "components/precache/core/precache_manifest_util.h" |
| 28 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/resource_request_info.h" | 28 #include "content/public/browser/resource_request_info.h" |
| 30 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
| 31 #include "net/http/http_response_headers.h" | 30 #include "net/http/http_response_headers.h" |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 const base::TimeTicks& first_contentful_paint) { | 491 const base::TimeTicks& first_contentful_paint) { |
| 493 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 492 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 494 if (initialization_state_ != INITIALIZED) | 493 if (initialization_state_ != INITIALIZED) |
| 495 return; | 494 return; |
| 496 | 495 |
| 497 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); | 496 NavigationMap::iterator nav_it = inflight_navigations_.find(navigation_id); |
| 498 if (nav_it != inflight_navigations_.end()) | 497 if (nav_it != inflight_navigations_.end()) |
| 499 nav_it->second->first_contentful_paint = first_contentful_paint; | 498 nav_it->second->first_contentful_paint = first_contentful_paint; |
| 500 } | 499 } |
| 501 | 500 |
| 502 void ResourcePrefetchPredictor::OnPrefetchingFinished( | |
| 503 const GURL& main_frame_url, | |
| 504 std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) { | |
| 505 if (observer_) | |
| 506 observer_->OnPrefetchingFinished(main_frame_url); | |
| 507 | |
| 508 if (stats_collector_) | |
| 509 stats_collector_->RecordPrefetcherStats(std::move(stats)); | |
| 510 } | |
| 511 | |
| 512 bool ResourcePrefetchPredictor::IsUrlPrefetchable( | 501 bool ResourcePrefetchPredictor::IsUrlPrefetchable( |
| 513 const GURL& main_frame_url) const { | 502 const GURL& main_frame_url) const { |
| 514 return GetPrefetchData(main_frame_url, nullptr); | 503 return GetPrefetchData(main_frame_url, nullptr); |
| 515 } | 504 } |
| 516 | 505 |
| 517 bool ResourcePrefetchPredictor::IsResourcePrefetchable( | 506 bool ResourcePrefetchPredictor::IsResourcePrefetchable( |
| 518 const ResourceData& resource) const { | 507 const ResourceData& resource) const { |
| 519 float confidence = static_cast<float>(resource.number_of_hits()) / | 508 float confidence = static_cast<float>(resource.number_of_hits()) / |
| 520 (resource.number_of_hits() + resource.number_of_misses()); | 509 (resource.number_of_hits() + resource.number_of_misses()); |
| 521 return confidence >= config_.min_resource_confidence_to_trigger_prefetch && | 510 return confidence >= config_.min_resource_confidence_to_trigger_prefetch && |
| 522 resource.number_of_hits() >= | 511 resource.number_of_hits() >= |
| 523 config_.min_resource_hits_to_trigger_prefetch; | 512 config_.min_resource_hits_to_trigger_prefetch; |
| 524 } | 513 } |
| 525 | 514 |
| 526 void ResourcePrefetchPredictor::SetObserverForTesting(TestObserver* observer) { | 515 void ResourcePrefetchPredictor::SetObserverForTesting(TestObserver* observer) { |
| 527 observer_ = observer; | 516 observer_ = observer; |
| 528 } | 517 } |
| 529 | 518 |
| 530 void ResourcePrefetchPredictor::SetStatsCollector( | 519 void ResourcePrefetchPredictor::SetStatsCollector( |
| 531 LoadingStatsCollector* stats_collector) { | 520 LoadingStatsCollector* stats_collector) { |
| 532 stats_collector_ = stats_collector; | 521 stats_collector_ = stats_collector; |
| 533 } | 522 } |
| 534 | 523 |
| 535 void ResourcePrefetchPredictor::Shutdown() { | 524 void ResourcePrefetchPredictor::Shutdown() { |
| 536 if (prefetch_manager_.get()) { | |
| 537 prefetch_manager_->ShutdownOnUIThread(); | |
| 538 prefetch_manager_ = nullptr; | |
| 539 } | |
| 540 history_service_observer_.RemoveAll(); | 525 history_service_observer_.RemoveAll(); |
| 541 } | 526 } |
| 542 | 527 |
| 543 void ResourcePrefetchPredictor::OnMainFrameRequest( | 528 void ResourcePrefetchPredictor::OnMainFrameRequest( |
| 544 const URLRequestSummary& request) { | 529 const URLRequestSummary& request) { |
| 545 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 530 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 546 DCHECK_EQ(INITIALIZED, initialization_state_); | 531 DCHECK_EQ(INITIALIZED, initialization_state_); |
| 547 | 532 |
| 548 CleanupAbandonedNavigations(request.navigation_id); | 533 CleanupAbandonedNavigations(request.navigation_id); |
| 549 | 534 |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 manifest_data_ = std::move(manifest_data); | 841 manifest_data_ = std::move(manifest_data); |
| 857 origin_data_ = std::move(origin_data); | 842 origin_data_ = std::move(origin_data); |
| 858 | 843 |
| 859 ConnectToHistoryService(); | 844 ConnectToHistoryService(); |
| 860 } | 845 } |
| 861 | 846 |
| 862 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { | 847 void ResourcePrefetchPredictor::OnHistoryAndCacheLoaded() { |
| 863 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 848 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 864 DCHECK_EQ(INITIALIZING, initialization_state_); | 849 DCHECK_EQ(INITIALIZING, initialization_state_); |
| 865 | 850 |
| 866 // Initialize the prefetch manager only if prefetching is enabled. | |
| 867 if (config_.IsPrefetchingEnabledForSomeOrigin(profile_)) { | |
| 868 prefetch_manager_ = new ResourcePrefetcherManager( | |
| 869 this, config_, profile_->GetRequestContext()); | |
| 870 } | |
| 871 initialization_state_ = INITIALIZED; | 851 initialization_state_ = INITIALIZED; |
| 872 | |
| 873 if (observer_) | 852 if (observer_) |
| 874 observer_->OnPredictorInitialized(); | 853 observer_->OnPredictorInitialized(); |
| 875 } | 854 } |
| 876 | 855 |
| 877 void ResourcePrefetchPredictor::CleanupAbandonedNavigations( | 856 void ResourcePrefetchPredictor::CleanupAbandonedNavigations( |
| 878 const NavigationID& navigation_id) { | 857 const NavigationID& navigation_id) { |
| 879 if (stats_collector_) | 858 if (stats_collector_) |
| 880 stats_collector_->CleanupAbandonedStats(); | 859 stats_collector_->CleanupAbandonedStats(); |
| 881 | 860 |
| 882 static const base::TimeDelta max_navigation_age = | 861 static const base::TimeDelta max_navigation_age = |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 if (!history_service) | 1358 if (!history_service) |
| 1380 return; | 1359 return; |
| 1381 DCHECK(!history_service_observer_.IsObserving(history_service)); | 1360 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 1382 history_service_observer_.Add(history_service); | 1361 history_service_observer_.Add(history_service); |
| 1383 if (history_service->BackendLoaded()) { | 1362 if (history_service->BackendLoaded()) { |
| 1384 // HistoryService is already loaded. Continue with Initialization. | 1363 // HistoryService is already loaded. Continue with Initialization. |
| 1385 OnHistoryAndCacheLoaded(); | 1364 OnHistoryAndCacheLoaded(); |
| 1386 } | 1365 } |
| 1387 } | 1366 } |
| 1388 | 1367 |
| 1389 void ResourcePrefetchPredictor::StartPrefetching( | |
| 1390 const GURL& url, | |
| 1391 const ResourcePrefetchPredictor::Prediction& prediction) { | |
| 1392 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url", | |
| 1393 url.spec()); | |
| 1394 if (!prefetch_manager_.get()) // Not enabled. | |
| 1395 return; | |
| 1396 | |
| 1397 BrowserThread::PostTask( | |
| 1398 BrowserThread::IO, FROM_HERE, | |
| 1399 base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch, | |
| 1400 prefetch_manager_, url, prediction.subresource_urls)); | |
| 1401 | |
| 1402 if (observer_) | |
| 1403 observer_->OnPrefetchingStarted(url); | |
| 1404 } | |
| 1405 | |
| 1406 void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) { | |
| 1407 TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url", | |
| 1408 url.spec()); | |
| 1409 if (!prefetch_manager_.get()) // Not enabled. | |
| 1410 return; | |
| 1411 | |
| 1412 BrowserThread::PostTask( | |
| 1413 BrowserThread::IO, FROM_HERE, | |
| 1414 base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch, | |
| 1415 prefetch_manager_, url)); | |
| 1416 | |
| 1417 if (observer_) | |
| 1418 observer_->OnPrefetchingStopped(url); | |
| 1419 } | |
| 1420 | |
| 1421 //////////////////////////////////////////////////////////////////////////////// | 1368 //////////////////////////////////////////////////////////////////////////////// |
| 1422 // TestObserver. | 1369 // TestObserver. |
| 1423 | 1370 |
| 1424 TestObserver::~TestObserver() { | 1371 TestObserver::~TestObserver() { |
| 1425 predictor_->SetObserverForTesting(nullptr); | 1372 predictor_->SetObserverForTesting(nullptr); |
| 1426 } | 1373 } |
| 1427 | 1374 |
| 1428 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) | 1375 TestObserver::TestObserver(ResourcePrefetchPredictor* predictor) |
| 1429 : predictor_(predictor) { | 1376 : predictor_(predictor) { |
| 1430 predictor_->SetObserverForTesting(this); | 1377 predictor_->SetObserverForTesting(this); |
| 1431 } | 1378 } |
| 1432 | 1379 |
| 1433 } // namespace predictors | 1380 } // namespace predictors |
| OLD | NEW |