predictors: Refactor resource_prefetch_predictor triggering.
Triggering and policy move to LoadingPredictor, instead of being in
ResourcePrefetchPredictor. As a consequence, rename
ResourcePrefetchPredictorObserver.
BUG=715525
Review-Url: https://codereview.chromium.org/2887133003
Cr-Commit-Position: refs/heads/master@{#476313}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index f5c2bb7..189880ba 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -696,6 +696,8 @@
"net/file_downloader.h",
"net/http_server_properties_manager_factory.cc",
"net/http_server_properties_manager_factory.h",
+ "net/loading_predictor_observer.cc",
+ "net/loading_predictor_observer.h",
"net/net_error_diagnostics_dialog.h",
"net/net_error_diagnostics_dialog_mac.cc",
"net/net_error_diagnostics_dialog_win.cc",
@@ -723,8 +725,6 @@
"net/referrer.h",
"net/request_source_bandwidth_histograms.cc",
"net/request_source_bandwidth_histograms.h",
- "net/resource_prefetch_predictor_observer.cc",
- "net/resource_prefetch_predictor_observer.h",
"net/safe_search_util.cc",
"net/safe_search_util.h",
"net/sdch_owner_pref_storage.cc",
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index 0d8316e..4168a51 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -26,7 +26,7 @@
#include "chrome/browser/loader/predictor_resource_throttle.h"
#include "chrome/browser/loader/safe_browsing_resource_throttle.h"
#include "chrome/browser/mod_pagespeed/mod_pagespeed_metrics.h"
-#include "chrome/browser/net/resource_prefetch_predictor_observer.h"
+#include "chrome/browser/net/loading_predictor_observer.h"
#include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
#include "chrome/browser/plugins/plugin_prefs.h"
#include "chrome/browser/prerender/prerender_manager.h"
@@ -536,8 +536,8 @@
resource_type, throttles);
#endif // !defined(DISABLE_NACL)
- if (io_data->resource_prefetch_predictor_observer()) {
- io_data->resource_prefetch_predictor_observer()->OnRequestStarted(
+ if (io_data->loading_predictor_observer()) {
+ io_data->loading_predictor_observer()->OnRequestStarted(
request, resource_type, info->GetWebContentsGetterForRequest());
}
}
@@ -811,8 +811,8 @@
}
#endif
- if (io_data->resource_prefetch_predictor_observer())
- io_data->resource_prefetch_predictor_observer()->OnResponseStarted(
+ if (io_data->loading_predictor_observer())
+ io_data->loading_predictor_observer()->OnResponseStarted(
request, info->GetWebContentsGetterForRequest());
mod_pagespeed::RecordMetrics(info->GetResourceType(), request->url(),
@@ -837,8 +837,8 @@
signin::FixMirrorRequestHeaderHelper(request, redirect_url, io_data,
info->GetChildID(), info->GetRouteID());
- if (io_data->resource_prefetch_predictor_observer()) {
- io_data->resource_prefetch_predictor_observer()->OnRequestRedirected(
+ if (io_data->loading_predictor_observer()) {
+ io_data->loading_predictor_observer()->OnRequestRedirected(
request, redirect_url, info->GetWebContentsGetterForRequest());
}
diff --git a/chrome/browser/net/resource_prefetch_predictor_observer.cc b/chrome/browser/net/loading_predictor_observer.cc
similarity index 76%
rename from chrome/browser/net/resource_prefetch_predictor_observer.cc
rename to chrome/browser/net/loading_predictor_observer.cc
index 4dc2b0b..8d48d01 100644
--- a/chrome/browser/net/resource_prefetch_predictor_observer.cc
+++ b/chrome/browser/net/loading_predictor_observer.cc
@@ -1,8 +1,8 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/net/resource_prefetch_predictor_observer.h"
+#include "chrome/browser/net/loading_predictor_observer.h"
#include <memory>
#include <string>
@@ -20,6 +20,7 @@
}
using content::BrowserThread;
+using predictors::LoadingPredictor;
using predictors::ResourcePrefetchPredictor;
using URLRequestSummary =
predictors::ResourcePrefetchPredictor::URLRequestSummary;
@@ -48,15 +49,13 @@
};
void ReportRequestStats(RequestStats stat) {
- UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.RequestStats",
- stat,
+ UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.RequestStats", stat,
REQUEST_STATS_MAX);
}
void ReportMainFrameRequestStats(MainFrameRequestStats stat) {
UMA_HISTOGRAM_ENUMERATION("ResourcePrefetchPredictor.MainFrameRequestStats",
- stat,
- MAIN_FRAME_REQUEST_STATS_MAX);
+ stat, MAIN_FRAME_REQUEST_STATS_MAX);
}
bool TryToFillNavigationID(
@@ -79,18 +78,17 @@
namespace chrome_browser_net {
-ResourcePrefetchPredictorObserver::ResourcePrefetchPredictorObserver(
- ResourcePrefetchPredictor* predictor)
+LoadingPredictorObserver::LoadingPredictorObserver(LoadingPredictor* predictor)
: predictor_(predictor->AsWeakPtr()) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
-ResourcePrefetchPredictorObserver::~ResourcePrefetchPredictorObserver() {
+LoadingPredictorObserver::~LoadingPredictorObserver() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
BrowserThread::CurrentlyOn(BrowserThread::IO));
}
-void ResourcePrefetchPredictorObserver::OnRequestStarted(
+void LoadingPredictorObserver::OnRequestStarted(
net::URLRequest* request,
content::ResourceType resource_type,
const content::ResourceRequestInfo::WebContentsGetter&
@@ -109,17 +107,16 @@
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &ResourcePrefetchPredictorObserver::OnRequestStartedOnUIThread,
- base::Unretained(this), base::Passed(std::move(summary)),
- web_contents_getter, request->first_party_for_cookies(),
- request->creation_time()));
+ base::BindOnce(&LoadingPredictorObserver::OnRequestStartedOnUIThread,
+ base::Unretained(this), base::Passed(std::move(summary)),
+ web_contents_getter, request->first_party_for_cookies(),
+ request->creation_time()));
if (resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
ReportMainFrameRequestStats(MAIN_FRAME_REQUEST_STATS_PROCESSED_REQUESTS);
}
-void ResourcePrefetchPredictorObserver::OnRequestRedirected(
+void LoadingPredictorObserver::OnRequestRedirected(
net::URLRequest* request,
const GURL& redirect_url,
const content::ResourceRequestInfo::WebContentsGetter&
@@ -145,11 +142,10 @@
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &ResourcePrefetchPredictorObserver::OnRequestRedirectedOnUIThread,
- base::Unretained(this), base::Passed(std::move(summary)),
- web_contents_getter, request->first_party_for_cookies(),
- request->creation_time()));
+ base::BindOnce(&LoadingPredictorObserver::OnRequestRedirectedOnUIThread,
+ base::Unretained(this), base::Passed(std::move(summary)),
+ web_contents_getter, request->first_party_for_cookies(),
+ request->creation_time()));
if (request_info &&
request_info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME) {
@@ -157,7 +153,7 @@
}
}
-void ResourcePrefetchPredictorObserver::OnResponseStarted(
+void LoadingPredictorObserver::OnResponseStarted(
net::URLRequest* request,
const content::ResourceRequestInfo::WebContentsGetter&
web_contents_getter) {
@@ -182,11 +178,10 @@
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &ResourcePrefetchPredictorObserver::OnResponseStartedOnUIThread,
- base::Unretained(this), base::Passed(std::move(summary)),
- web_contents_getter, request->first_party_for_cookies(),
- request->creation_time()));
+ base::BindOnce(&LoadingPredictorObserver::OnResponseStartedOnUIThread,
+ base::Unretained(this), base::Passed(std::move(summary)),
+ web_contents_getter, request->first_party_for_cookies(),
+ request->creation_time()));
ReportRequestStats(REQUEST_STATS_TOTAL_PROCESSED_RESPONSES);
if (request_info &&
@@ -195,7 +190,7 @@
}
}
-void ResourcePrefetchPredictorObserver::OnRequestStartedOnUIThread(
+void LoadingPredictorObserver::OnRequestStartedOnUIThread(
std::unique_ptr<URLRequestSummary> summary,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
const GURL& main_frame_url,
@@ -205,10 +200,12 @@
main_frame_url, creation_time)) {
return;
}
- predictor_->RecordURLRequest(*summary);
+ if (summary->resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
+ predictor_->OnMainFrameRequest(*summary);
+ predictor_->resource_prefetch_predictor()->RecordURLRequest(*summary);
}
-void ResourcePrefetchPredictorObserver::OnRequestRedirectedOnUIThread(
+void LoadingPredictorObserver::OnRequestRedirectedOnUIThread(
std::unique_ptr<URLRequestSummary> summary,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
const GURL& main_frame_url,
@@ -218,10 +215,12 @@
main_frame_url, creation_time)) {
return;
}
- predictor_->RecordURLRedirect(*summary);
+ if (summary->resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
+ predictor_->OnMainFrameRedirect(*summary);
+ predictor_->resource_prefetch_predictor()->RecordURLRedirect(*summary);
}
-void ResourcePrefetchPredictorObserver::OnResponseStartedOnUIThread(
+void LoadingPredictorObserver::OnResponseStartedOnUIThread(
std::unique_ptr<URLRequestSummary> summary,
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
const GURL& main_frame_url,
@@ -231,7 +230,9 @@
main_frame_url, creation_time)) {
return;
}
- predictor_->RecordURLResponse(*summary);
+ if (summary->resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
+ predictor_->OnMainFrameResponse(*summary);
+ predictor_->resource_prefetch_predictor()->RecordURLResponse(*summary);
}
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/resource_prefetch_predictor_observer.h b/chrome/browser/net/loading_predictor_observer.h
similarity index 79%
rename from chrome/browser/net/resource_prefetch_predictor_observer.h
rename to chrome/browser/net/loading_predictor_observer.h
index 4801540..4753f51b 100644
--- a/chrome/browser/net/resource_prefetch_predictor_observer.h
+++ b/chrome/browser/net/loading_predictor_observer.h
@@ -1,14 +1,15 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_NET_RESOURCE_PREFETCH_PREDICTOR_OBSERVER_H_
-#define CHROME_BROWSER_NET_RESOURCE_PREFETCH_PREDICTOR_OBSERVER_H_
+#ifndef CHROME_BROWSER_NET_LOADING_PREDICTOR_OBSERVER_H_
+#define CHROME_BROWSER_NET_LOADING_PREDICTOR_OBSERVER_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_type.h"
@@ -22,17 +23,16 @@
namespace chrome_browser_net {
// Observes resource requests in the ResourceDispatcherHostDelegate and notifies
-// the ResourcePrefetchPredictor about the ones it is interested in.
+// the LoadingPredictor about the ones it is interested in.
// - Has an instance per profile, and is owned by the corresponding
// ProfileIOData.
// - Needs to be constructed on UI thread. Can be destroyed on UI or IO thread.
// As for member functions, public members are meant to be called on the IO
// thread and private members from the UI thread.
-class ResourcePrefetchPredictorObserver {
+class LoadingPredictorObserver {
public:
- explicit ResourcePrefetchPredictorObserver(
- predictors::ResourcePrefetchPredictor* predictor);
- ~ResourcePrefetchPredictorObserver();
+ explicit LoadingPredictorObserver(predictors::LoadingPredictor* predictor);
+ ~LoadingPredictorObserver();
// Parts of the ResourceDispatcherHostDelegate that we want to observe.
void OnRequestStarted(net::URLRequest* request,
@@ -72,11 +72,11 @@
const base::TimeTicks& creation_time) const;
// Owned by profile.
- base::WeakPtr<predictors::ResourcePrefetchPredictor> predictor_;
+ base::WeakPtr<predictors::LoadingPredictor> predictor_;
- DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorObserver);
+ DISALLOW_COPY_AND_ASSIGN(LoadingPredictorObserver);
};
} // namespace chrome_browser_net
-#endif // CHROME_BROWSER_NET_RESOURCE_PREFETCH_PREDICTOR_OBSERVER_H_
+#endif // CHROME_BROWSER_NET_LOADING_PREDICTOR_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/observers/resource_prefetch_predictor_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/resource_prefetch_predictor_page_load_metrics_observer_unittest.cc
index 1251655..64cbc254 100644
--- a/chrome/browser/page_load_metrics/observers/resource_prefetch_predictor_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/resource_prefetch_predictor_page_load_metrics_observer_unittest.cc
@@ -23,7 +23,7 @@
Profile* profile)
: ResourcePrefetchPredictor(config, profile) {}
- MOCK_METHOD1(IsUrlPrefetchable, bool(const GURL& main_frame_url));
+ MOCK_CONST_METHOD1(IsUrlPrefetchable, bool(const GURL& main_frame_url));
~MockResourcePrefetchPredictor() override {}
};
diff --git a/chrome/browser/predictors/loading_predictor.cc b/chrome/browser/predictors/loading_predictor.cc
index d5bd264..e818418 100644
--- a/chrome/browser/predictors/loading_predictor.cc
+++ b/chrome/browser/predictors/loading_predictor.cc
@@ -5,24 +5,37 @@
#include "chrome/browser/predictors/loading_predictor.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "chrome/browser/predictors/resource_prefetch_common.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h"
namespace predictors {
+using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
+
LoadingPredictor::LoadingPredictor(const LoadingPredictorConfig& config,
- Profile* profile) {
- resource_prefetch_predictor_ =
- base::MakeUnique<ResourcePrefetchPredictor>(config, profile);
-}
+ Profile* profile)
+ : config_(config),
+ profile_(profile),
+ resource_prefetch_predictor_(
+ base::MakeUnique<ResourcePrefetchPredictor>(config, profile)) {}
LoadingPredictor::~LoadingPredictor() = default;
void LoadingPredictor::PrepareForPageLoad(const GURL& url, HintOrigin origin) {
- resource_prefetch_predictor_->StartPrefetching(url, origin);
+ if (active_hints_.find(url) != active_hints_.end() ||
+ !resource_prefetch_predictor_->IsUrlPrefetchable(url))
+ return;
+
+ // To report hint durations.
+ active_hints_.emplace(url, base::TimeTicks::Now());
+
+ if (config_.IsPrefetchingEnabledForOrigin(profile_, origin))
+ resource_prefetch_predictor_->StartPrefetching(url);
}
void LoadingPredictor::CancelPageLoadHint(const GURL& url) {
- resource_prefetch_predictor_->StopPrefetching(url);
+ CancelActiveHint(active_hints_.find(url));
}
void LoadingPredictor::StartInitialization() {
@@ -38,4 +51,87 @@
resource_prefetch_predictor_->Shutdown();
}
+void LoadingPredictor::OnMainFrameRequest(const URLRequestSummary& summary) {
+ DCHECK(summary.resource_type == content::RESOURCE_TYPE_MAIN_FRAME);
+
+ const NavigationID& navigation_id = summary.navigation_id;
+ CleanupAbandonedHintsAndNavigations(navigation_id);
+ active_navigations_.emplace(navigation_id, navigation_id.main_frame_url);
+ PrepareForPageLoad(navigation_id.main_frame_url, HintOrigin::NAVIGATION);
+}
+
+void LoadingPredictor::OnMainFrameRedirect(const URLRequestSummary& summary) {
+ DCHECK(summary.resource_type == content::RESOURCE_TYPE_MAIN_FRAME);
+
+ auto it = active_navigations_.find(summary.navigation_id);
+ if (it != active_navigations_.end()) {
+ if (summary.navigation_id.main_frame_url == summary.redirect_url)
+ return;
+ NavigationID navigation_id = summary.navigation_id;
+ navigation_id.main_frame_url = summary.redirect_url;
+ active_navigations_.emplace(navigation_id, it->second);
+ active_navigations_.erase(it);
+ }
+}
+
+void LoadingPredictor::OnMainFrameResponse(const URLRequestSummary& summary) {
+ DCHECK(summary.resource_type == content::RESOURCE_TYPE_MAIN_FRAME);
+
+ const NavigationID& navigation_id = summary.navigation_id;
+ auto it = active_navigations_.find(navigation_id);
+ if (it != active_navigations_.end()) {
+ const GURL& initial_url = it->second;
+ CancelPageLoadHint(initial_url);
+ active_navigations_.erase(it);
+ } else {
+ CancelPageLoadHint(navigation_id.main_frame_url);
+ }
+}
+
+std::map<GURL, base::TimeTicks>::iterator LoadingPredictor::CancelActiveHint(
+ std::map<GURL, base::TimeTicks>::iterator hint_it) {
+ if (hint_it == active_hints_.end())
+ return hint_it;
+
+ const GURL& url = hint_it->first;
+ resource_prefetch_predictor_->StopPrefetching(url);
+
+ UMA_HISTOGRAM_TIMES(
+ internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
+ base::TimeTicks::Now() - hint_it->second);
+ return active_hints_.erase(hint_it);
+}
+
+void LoadingPredictor::CleanupAbandonedHintsAndNavigations(
+ const NavigationID& navigation_id) {
+ base::TimeTicks time_now = base::TimeTicks::Now();
+ const base::TimeDelta max_navigation_age =
+ base::TimeDelta::FromSeconds(config_.max_navigation_lifetime_seconds);
+
+ // Hints.
+ for (auto it = active_hints_.begin(); it != active_hints_.end();) {
+ base::TimeDelta prefetch_age = time_now - it->second;
+ if (prefetch_age > max_navigation_age) {
+ // Will go to the last bucket in the duration reported in
+ // CancelActiveHint() meaning that the duration was unlimited.
+ it = CancelActiveHint(it);
+ } else {
+ ++it;
+ }
+ }
+
+ // Navigations.
+ for (auto it = active_navigations_.begin();
+ it != active_navigations_.end();) {
+ if ((it->first.tab_id == navigation_id.tab_id) ||
+ (time_now - it->first.creation_time > max_navigation_age)) {
+ const GURL& initial_url = it->second;
+ CancelActiveHint(active_hints_.find(initial_url));
+ it = active_navigations_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
} // namespace predictors
diff --git a/chrome/browser/predictors/loading_predictor.h b/chrome/browser/predictors/loading_predictor.h
index 9bcdd81..4588febb 100644
--- a/chrome/browser/predictors/loading_predictor.h
+++ b/chrome/browser/predictors/loading_predictor.h
@@ -5,12 +5,17 @@
#ifndef CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_H_
#define CHROME_BROWSER_PREDICTORS_LOADING_PREDICTOR_H_
+#include <map>
#include <memory>
+#include <utility>
+#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
#include "chrome/browser/predictors/resource_prefetch_common.h"
#include "chrome/browser/predictors/resource_prefetch_predictor.h"
#include "components/keyed_service/core/keyed_service.h"
+#include "url/gurl.h"
class Profile;
@@ -22,6 +27,9 @@
// From a high-level request (GURL and motivation) and a database of historical
// data, initiates predictive actions to speed up page loads.
//
+// Also listens to main frame requests/redirects/responses to initiate and
+// cancel page load hints.
+//
// See ResourcePrefetchPredictor for a description of the resource prefetch
// predictor.
//
@@ -48,8 +56,45 @@
// KeyedService:
void Shutdown() override;
+ void OnMainFrameRequest(
+ const ResourcePrefetchPredictor::URLRequestSummary& summary);
+ void OnMainFrameRedirect(
+ const ResourcePrefetchPredictor::URLRequestSummary& summary);
+ void OnMainFrameResponse(
+ const ResourcePrefetchPredictor::URLRequestSummary& summary);
+
private:
+ // Cancels an active hint, from its iterator inside |active_hints_|. If the
+ // iterator is .end(), does nothing. Returns the iterator after deletion of
+ // the entry.
+ std::map<GURL, base::TimeTicks>::iterator CancelActiveHint(
+ std::map<GURL, base::TimeTicks>::iterator hint_it);
+ void CleanupAbandonedHintsAndNavigations(const NavigationID& navigation_id);
+
+ // For testing.
+ void set_mock_resource_prefetch_predictor(
+ std::unique_ptr<ResourcePrefetchPredictor> predictor) {
+ resource_prefetch_predictor_ = std::move(predictor);
+ }
+
+ LoadingPredictorConfig config_;
+ Profile* profile_;
std::unique_ptr<ResourcePrefetchPredictor> resource_prefetch_predictor_;
+ std::map<GURL, base::TimeTicks> active_hints_;
+ // Initial URL.
+ std::map<NavigationID, GURL> active_navigations_;
+
+ friend class LoadingPredictorTest;
+ FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest,
+ TestMainFrameResponseCancelsHint);
+ FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest,
+ TestMainFrameRequestCancelsStaleNavigations);
+ FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest,
+ TestMainFrameResponseClearsNavigations);
+ FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest,
+ TestMainFrameRequestDoesntCancelExternalHint);
+ FRIEND_TEST_ALL_PREFIXES(LoadingPredictorTest,
+ TestDontTrackNonPrefetchableUrls);
DISALLOW_COPY_AND_ASSIGN(LoadingPredictor);
};
diff --git a/chrome/browser/predictors/loading_predictor_unittest.cc b/chrome/browser/predictors/loading_predictor_unittest.cc
new file mode 100644
index 0000000..f9faee40
--- /dev/null
+++ b/chrome/browser/predictors/loading_predictor_unittest.cc
@@ -0,0 +1,219 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/predictors/loading_predictor.h"
+
+#include <memory>
+#include <set>
+#include <string>
+
+#include "base/run_loop.h"
+#include "base/test/histogram_tester.h"
+#include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace predictors {
+
+namespace {
+// First two are prefetchable, last one is not (see SetUp()).
+const char kUrl[] = "http://www.google.com/cats";
+const char kUrl2[] = "http://www.google.com/dogs";
+const char kUrl3[] = "https://unknown.website/catsanddogs";
+}
+
+// Does nothing, controls which URLs are prefetchable.
+class MockResourcePrefetcherPredictor : public ResourcePrefetchPredictor {
+ public:
+ MockResourcePrefetcherPredictor(const LoadingPredictorConfig& config,
+ Profile* profile)
+ : ResourcePrefetchPredictor(config, profile) {}
+
+ bool IsUrlPrefetchable(const GURL& main_frame_url) const override {
+ return prefetchable_urls_.find(main_frame_url) != prefetchable_urls_.end();
+ }
+
+ void AddPrefetchableUrl(const GURL& url) { prefetchable_urls_.insert(url); }
+
+ MOCK_METHOD0(StartInitialization, void());
+ MOCK_METHOD0(Shutdown, void());
+ MOCK_METHOD1(StartPrefetching, void(const GURL&));
+ MOCK_METHOD1(StopPrefeching, void(const GURL&));
+
+ private:
+ std::set<GURL> prefetchable_urls_;
+};
+
+class LoadingPredictorTest : public testing::Test {
+ public:
+ LoadingPredictorTest();
+ ~LoadingPredictorTest() override;
+ void SetUp() override;
+ void TearDown() override;
+
+ protected:
+ content::TestBrowserThreadBundle thread_bundle_;
+ std::unique_ptr<LoadingPredictor> predictor_;
+ std::unique_ptr<TestingProfile> profile_;
+};
+
+LoadingPredictorTest::LoadingPredictorTest()
+ : profile_(base::MakeUnique<TestingProfile>()) {}
+
+LoadingPredictorTest::~LoadingPredictorTest() {
+ profile_ = nullptr;
+ base::RunLoop().RunUntilIdle();
+}
+
+void LoadingPredictorTest::SetUp() {
+ LoadingPredictorConfig config;
+ PopulateTestConfig(&config);
+ predictor_ = base::MakeUnique<LoadingPredictor>(config, profile_.get());
+ auto mock =
+ base::MakeUnique<MockResourcePrefetcherPredictor>(config, profile_.get());
+ mock->AddPrefetchableUrl(GURL(kUrl));
+ mock->AddPrefetchableUrl(GURL(kUrl2));
+ predictor_->set_mock_resource_prefetch_predictor(std::move(mock));
+ predictor_->StartInitialization();
+ base::RunLoop().RunUntilIdle();
+}
+
+void LoadingPredictorTest::TearDown() {
+ predictor_ = nullptr;
+ profile_->DestroyHistoryService();
+}
+
+TEST_F(LoadingPredictorTest, TestPrefetchingDurationHistogram) {
+ base::HistogramTester histogram_tester;
+
+ const GURL url = GURL(kUrl);
+ const GURL url2 = GURL(kUrl2);
+ const GURL url3 = GURL(kUrl3);
+ predictor_->PrepareForPageLoad(url, HintOrigin::EXTERNAL);
+ predictor_->CancelPageLoadHint(url);
+ histogram_tester.ExpectTotalCount(
+ internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 1);
+
+ // Mismatched start / end.
+ predictor_->PrepareForPageLoad(url, HintOrigin::EXTERNAL);
+ predictor_->CancelPageLoadHint(url2);
+ // No increment.
+ histogram_tester.ExpectTotalCount(
+ internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 1);
+
+ // Can track a navigation (url2) while one is still in progress (url).
+ predictor_->PrepareForPageLoad(url2, HintOrigin::EXTERNAL);
+ predictor_->CancelPageLoadHint(url2);
+ histogram_tester.ExpectTotalCount(
+ internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 2);
+
+ // Do not track non-prefetchable URLs.
+ predictor_->PrepareForPageLoad(url3, HintOrigin::EXTERNAL);
+ predictor_->CancelPageLoadHint(url3);
+ // No increment.
+ histogram_tester.ExpectTotalCount(
+ internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 2);
+}
+
+TEST_F(LoadingPredictorTest, TestMainFrameResponseCancelsHint) {
+ const GURL url = GURL(kUrl);
+ predictor_->PrepareForPageLoad(url, HintOrigin::EXTERNAL);
+ EXPECT_EQ(1UL, predictor_->active_hints_.size());
+
+ auto summary = CreateURLRequestSummary(12, url.spec());
+ predictor_->OnMainFrameResponse(summary);
+ EXPECT_TRUE(predictor_->active_hints_.empty());
+}
+
+TEST_F(LoadingPredictorTest, TestMainFrameRequestCancelsStaleNavigations) {
+ const std::string url = kUrl;
+ const std::string url2 = kUrl2;
+ const int tab_id = 12;
+ const auto& active_navigations = predictor_->active_navigations_;
+ const auto& active_hints = predictor_->active_hints_;
+
+ auto summary = CreateURLRequestSummary(tab_id, url);
+ auto navigation_id = CreateNavigationID(tab_id, url);
+
+ predictor_->OnMainFrameRequest(summary);
+ EXPECT_NE(active_navigations.find(navigation_id), active_navigations.end());
+ EXPECT_NE(active_hints.find(GURL(url)), active_hints.end());
+
+ summary = CreateURLRequestSummary(tab_id, url2);
+ predictor_->OnMainFrameRequest(summary);
+ EXPECT_EQ(active_navigations.find(navigation_id), active_navigations.end());
+ EXPECT_EQ(active_hints.find(GURL(url)), active_hints.end());
+
+ auto navigation_id2 = CreateNavigationID(tab_id, url2);
+ EXPECT_NE(active_navigations.find(navigation_id2), active_navigations.end());
+}
+
+TEST_F(LoadingPredictorTest, TestMainFrameResponseClearsNavigations) {
+ const std::string url = kUrl;
+ const std::string redirected = kUrl2;
+ const int tab_id = 12;
+ const auto& active_navigations = predictor_->active_navigations_;
+ const auto& active_hints = predictor_->active_hints_;
+
+ auto summary = CreateURLRequestSummary(tab_id, url);
+ auto navigation_id = CreateNavigationID(tab_id, url);
+
+ predictor_->OnMainFrameRequest(summary);
+ EXPECT_NE(active_navigations.find(navigation_id), active_navigations.end());
+ EXPECT_FALSE(active_hints.empty());
+
+ predictor_->OnMainFrameResponse(summary);
+ EXPECT_TRUE(active_navigations.empty());
+ EXPECT_TRUE(active_hints.empty());
+
+ // With redirects.
+ predictor_->OnMainFrameRequest(summary);
+ EXPECT_NE(active_navigations.find(navigation_id), active_navigations.end());
+ EXPECT_FALSE(active_hints.empty());
+
+ summary.redirect_url = GURL(redirected);
+ predictor_->OnMainFrameRedirect(summary);
+ EXPECT_FALSE(active_navigations.empty());
+ EXPECT_FALSE(active_hints.empty());
+
+ summary.navigation_id.main_frame_url = GURL(redirected);
+ predictor_->OnMainFrameResponse(summary);
+ EXPECT_TRUE(active_navigations.empty());
+ EXPECT_TRUE(active_hints.empty());
+}
+
+TEST_F(LoadingPredictorTest, TestMainFrameRequestDoesntCancelExternalHint) {
+ const GURL url = GURL(kUrl);
+ const int tab_id = 12;
+ const auto& active_navigations = predictor_->active_navigations_;
+ auto& active_hints = predictor_->active_hints_;
+
+ predictor_->PrepareForPageLoad(url, HintOrigin::EXTERNAL);
+ auto it = active_hints.find(url);
+ EXPECT_NE(it, active_hints.end());
+ EXPECT_TRUE(active_navigations.empty());
+
+ // To check that the hint is not replaced, set the start time in the past,
+ // and check later that it didn't change.
+ base::TimeTicks start_time = it->second - base::TimeDelta::FromSeconds(10);
+ it->second = start_time;
+
+ auto summary = CreateURLRequestSummary(tab_id, url.spec());
+ predictor_->OnMainFrameRequest(summary);
+ EXPECT_NE(active_navigations.find(summary.navigation_id),
+ active_navigations.end());
+ it = active_hints.find(url);
+ EXPECT_NE(it, active_hints.end());
+ EXPECT_EQ(start_time, it->second);
+}
+
+TEST_F(LoadingPredictorTest, TestDontTrackNonPrefetchableUrls) {
+ const GURL url3 = GURL(kUrl3);
+ predictor_->PrepareForPageLoad(url3, HintOrigin::EXTERNAL);
+ EXPECT_TRUE(predictor_->active_hints_.empty());
+}
+
+} // namespace predictors
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.cc b/chrome/browser/predictors/resource_prefetch_predictor.cc
index ecb50a4..11f0b234 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor.cc
@@ -628,9 +628,7 @@
if (initialization_state_ != INITIALIZED)
return;
- if (response.resource_type == content::RESOURCE_TYPE_MAIN_FRAME)
- OnMainFrameResponse(response);
- else
+ if (response.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
OnSubresourceResponse(response);
}
@@ -678,56 +676,6 @@
nav_it->second->first_contentful_paint = first_contentful_paint;
}
-void ResourcePrefetchPredictor::StartPrefetching(const GURL& url,
- HintOrigin origin) {
- TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
- url.spec());
- // Save prefetch start time to report prefetching duration.
- if (inflight_prefetches_.find(url) == inflight_prefetches_.end() &&
- IsUrlPrefetchable(url)) {
- inflight_prefetches_.insert(std::make_pair(url, base::TimeTicks::Now()));
- }
-
- if (!prefetch_manager_.get()) // Prefetching not enabled.
- return;
- if (!config_.IsPrefetchingEnabledForOrigin(profile_, origin))
- return;
-
- ResourcePrefetchPredictor::Prediction prediction;
- if (!GetPrefetchData(url, &prediction))
- return;
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch,
- prefetch_manager_, url, prediction.subresource_urls));
-
- if (observer_)
- observer_->OnPrefetchingStarted(url);
-}
-
-void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
- TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
- url.spec());
- auto it = inflight_prefetches_.find(url);
- if (it != inflight_prefetches_.end()) {
- UMA_HISTOGRAM_TIMES(
- internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
- base::TimeTicks::Now() - it->second);
- inflight_prefetches_.erase(it);
- }
- if (!prefetch_manager_.get()) // Not enabled.
- return;
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch,
- prefetch_manager_, url));
-
- if (observer_)
- observer_->OnPrefetchingStopped(url);
-}
-
void ResourcePrefetchPredictor::OnPrefetchingFinished(
const GURL& main_frame_url,
std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats) {
@@ -737,7 +685,8 @@
prefetcher_stats_.insert(std::make_pair(main_frame_url, std::move(stats)));
}
-bool ResourcePrefetchPredictor::IsUrlPrefetchable(const GURL& main_frame_url) {
+bool ResourcePrefetchPredictor::IsUrlPrefetchable(
+ const GURL& main_frame_url) const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (initialization_state_ != INITIALIZED)
return false;
@@ -771,30 +720,13 @@
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(INITIALIZED, initialization_state_);
- const GURL& main_frame_url = request.navigation_id.main_frame_url;
- StartPrefetching(main_frame_url, HintOrigin::NAVIGATION);
-
CleanupAbandonedNavigations(request.navigation_id);
// New empty navigation entry.
- inflight_navigations_.insert(
- std::make_pair(request.navigation_id,
- base::MakeUnique<PageRequestSummary>(main_frame_url)));
-}
-
-void ResourcePrefetchPredictor::OnMainFrameResponse(
- const URLRequestSummary& response) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_EQ(INITIALIZED, initialization_state_);
-
- NavigationMap::iterator nav_it =
- inflight_navigations_.find(response.navigation_id);
- if (nav_it != inflight_navigations_.end()) {
- // To match an URL in StartPrefetching().
- StopPrefetching(nav_it->second->initial_url);
- } else {
- StopPrefetching(response.navigation_id.main_frame_url);
- }
+ const GURL& main_frame_url = request.navigation_id.main_frame_url;
+ inflight_navigations_.emplace(
+ request.navigation_id,
+ base::MakeUnique<PageRequestSummary>(main_frame_url));
}
void ResourcePrefetchPredictor::OnMainFrameRedirect(
@@ -825,8 +757,7 @@
NavigationID navigation_id(response.navigation_id);
navigation_id.main_frame_url = response.redirect_url;
summary->main_frame_url = response.redirect_url;
- inflight_navigations_.insert(
- std::make_pair(navigation_id, std::move(summary)));
+ inflight_navigations_.emplace(navigation_id, std::move(summary));
}
void ResourcePrefetchPredictor::OnSubresourceResponse(
@@ -1079,20 +1010,6 @@
}
}
- for (auto it = inflight_prefetches_.begin();
- it != inflight_prefetches_.end();) {
- base::TimeDelta prefetch_age = time_now - it->second;
- if (prefetch_age > max_navigation_age) {
- // It goes to the last bucket meaning that the duration was unlimited.
- UMA_HISTOGRAM_TIMES(
- internal::kResourcePrefetchPredictorPrefetchingDurationHistogram,
- prefetch_age);
- it = inflight_prefetches_.erase(it);
- } else {
- ++it;
- }
- }
-
// Remove old prefetches that haven't been claimed.
for (auto stats_it = prefetcher_stats_.begin();
stats_it != prefetcher_stats_.end();) {
@@ -1599,6 +1516,40 @@
}
}
+void ResourcePrefetchPredictor::StartPrefetching(const GURL& url) {
+ TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StartPrefetching", "url",
+ url.spec());
+ if (!prefetch_manager_.get()) // Not enabled.
+ return;
+
+ ResourcePrefetchPredictor::Prediction prediction;
+ bool has_data = GetPrefetchData(url, &prediction);
+ DCHECK(has_data);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&ResourcePrefetcherManager::MaybeAddPrefetch,
+ prefetch_manager_, url, prediction.subresource_urls));
+
+ if (observer_)
+ observer_->OnPrefetchingStarted(url);
+}
+
+void ResourcePrefetchPredictor::StopPrefetching(const GURL& url) {
+ TRACE_EVENT1("browser", "ResourcePrefetchPredictor::StopPrefetching", "url",
+ url.spec());
+ if (!prefetch_manager_.get()) // Not enabled.
+ return;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&ResourcePrefetcherManager::MaybeRemovePrefetch,
+ prefetch_manager_, url));
+
+ if (observer_)
+ observer_->OnPrefetchingStopped(url);
+}
+
////////////////////////////////////////////////////////////////////////////////
// TestObserver.
diff --git a/chrome/browser/predictors/resource_prefetch_predictor.h b/chrome/browser/predictors/resource_prefetch_predictor.h
index f01b150..e8a88fb 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor.h
@@ -24,6 +24,7 @@
#include "chrome/browser/predictors/resource_prefetch_common.h"
#include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
#include "chrome/browser/predictors/resource_prefetcher.h"
+#include "chrome/browser/predictors/resource_prefetcher_manager.h"
#include "components/history/core/browser/history_db_task.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/history/core/browser/history_types.h"
@@ -214,9 +215,9 @@
~ResourcePrefetchPredictor() override;
// Starts initialization by posting a task to the DB thread to read the
- // predictor database.
- void StartInitialization();
- void Shutdown();
+ // predictor database. Virtual for testing.
+ virtual void StartInitialization();
+ virtual void Shutdown();
// Thread safe.
static bool ShouldRecordRequest(net::URLRequest* request,
@@ -258,7 +259,7 @@
std::unique_ptr<ResourcePrefetcher::PrefetcherStats> stats);
// Returns true if prefetching data exists for the |main_frame_url|.
- virtual bool IsUrlPrefetchable(const GURL& main_frame_url);
+ virtual bool IsUrlPrefetchable(const GURL& main_frame_url) const;
// Returns true iff |resource| has sufficient confidence level and required
// number of hits.
@@ -274,9 +275,9 @@
void SetObserverForTesting(TestObserver* observer);
private:
- // Starts prefetching if it is enabled for |origin| and prefetching data
- // exists for the |main_frame_url| either at the URL or at the host level.
- void StartPrefetching(const GURL& main_frame_url, HintOrigin origin);
+ // Starts prefetching if it is enabled and prefetching data exists for the
+ // |main_frame_url| either at the URL or at the host level.
+ void StartPrefetching(const GURL& main_frame_url);
// Stops prefetching that may be in progress corresponding to
// |main_frame_url|.
@@ -360,7 +361,6 @@
// Functions called on different network events pertaining to the loading of
// main frame resource or sub resources.
void OnMainFrameRequest(const URLRequestSummary& request);
- void OnMainFrameResponse(const URLRequestSummary& response);
void OnMainFrameRedirect(const URLRequestSummary& response);
void OnSubresourceResponse(const URLRequestSummary& response);
void OnSubresourceRedirect(const URLRequestSummary& response);
@@ -405,7 +405,7 @@
// database has been read.
void OnHistoryAndCacheLoaded();
- // Cleanup inflight_navigations_, inflight_prefetches_, and prefetcher_stats_.
+ // Cleanup inflight_navigations_, and prefetcher_stats_.
void CleanupAbandonedNavigations(const NavigationID& navigation_id);
// Deletes all URLs from the predictor database, the caches and removes all
@@ -463,6 +463,12 @@
tables_ = tables;
}
+ // For testing.
+ void set_mock_resource_prefetcher_manager(
+ scoped_refptr<ResourcePrefetcherManager> prefetch_manager) {
+ prefetch_manager_ = prefetch_manager;
+ }
+
Profile* const profile_;
TestObserver* observer_;
const LoadingPredictorConfig config_;
@@ -478,7 +484,6 @@
std::unique_ptr<ManifestDataMap> manifest_data_;
std::unique_ptr<OriginDataMap> origin_data_;
- std::map<GURL, base::TimeTicks> inflight_prefetches_;
NavigationMap inflight_navigations_;
std::map<GURL, std::unique_ptr<ResourcePrefetcher::PrefetcherStats>>
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc b/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
index 98af40f..a8a3762 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_test_util.cc
@@ -176,6 +176,22 @@
return summary;
}
+void PopulateTestConfig(LoadingPredictorConfig* config, bool small_db) {
+ if (small_db) {
+ config->max_urls_to_track = 3;
+ config->max_hosts_to_track = 2;
+ config->min_url_visit_count = 2;
+ config->max_resources_per_entry = 4;
+ config->max_consecutive_misses = 2;
+ config->max_redirect_consecutive_misses = 2;
+ config->min_resource_confidence_to_trigger_prefetch = 0.5;
+ }
+ config->is_url_learning_enabled = true;
+ config->is_manifests_enabled = true;
+ config->is_origin_learning_enabled = true;
+ config->mode = LoadingPredictorConfig::LEARNING;
+}
+
std::ostream& operator<<(std::ostream& os, const PrefetchData& data) {
os << "[" << data.primary_key() << "," << data.last_visit_time() << "]"
<< std::endl;
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_test_util.h b/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
index e66fedd7..d11f783 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
+++ b/chrome/browser/predictors/resource_prefetch_predictor_test_util.h
@@ -77,6 +77,8 @@
bool has_validators = false,
bool always_revalidate = false);
+void PopulateTestConfig(LoadingPredictorConfig* config, bool small_db = true);
+
// For printing failures nicely.
std::ostream& operator<<(std::ostream& stream, const PrefetchData& data);
std::ostream& operator<<(std::ostream& stream, const ResourceData& resource);
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
index 00383da..e67236a7 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -14,8 +14,10 @@
#include "base/test/histogram_tester.h"
#include "base/time/time.h"
#include "chrome/browser/history/history_service_factory.h"
+#include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
#include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h"
+#include "chrome/browser/predictors/resource_prefetcher_manager.h"
#include "chrome/test/base/testing_profile.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_types.h"
@@ -259,7 +261,7 @@
}
void InitializePredictor() {
- predictor_->StartInitialization();
+ loading_predictor_->StartInitialization();
base::RunLoop loop;
loop.RunUntilIdle(); // Runs the DB lookup.
profile_->BlockUntilHistoryProcessesPendingRequests();
@@ -267,20 +269,10 @@
void ResetPredictor(bool small_db = true) {
LoadingPredictorConfig config;
- if (small_db) {
- config.max_urls_to_track = 3;
- config.max_hosts_to_track = 2;
- config.max_resources_per_entry = 4;
- config.max_consecutive_misses = 2;
- config.max_redirect_consecutive_misses = 2;
- config.min_resource_confidence_to_trigger_prefetch = 0.5;
- }
- config.is_url_learning_enabled = true;
- config.is_manifests_enabled = true;
- config.is_origin_learning_enabled = true;
-
- config.mode |= LoadingPredictorConfig::LEARNING;
- predictor_.reset(new ResourcePrefetchPredictor(config, profile_.get()));
+ PopulateTestConfig(&config, small_db);
+ loading_predictor_ =
+ base::MakeUnique<LoadingPredictor>(config, profile_.get());
+ predictor_ = loading_predictor_->resource_prefetch_predictor();
predictor_->set_mock_tables(mock_tables_);
}
@@ -296,7 +288,8 @@
std::unique_ptr<TestingProfile> profile_;
net::TestURLRequestContext url_request_context_;
- std::unique_ptr<ResourcePrefetchPredictor> predictor_;
+ std::unique_ptr<LoadingPredictor> loading_predictor_;
+ ResourcePrefetchPredictor* predictor_;
scoped_refptr<StrictMock<MockResourcePrefetchPredictorTables>> mock_tables_;
PrefetchDataMap test_url_data_;
@@ -355,7 +348,8 @@
mock_tables_->manifest_table_.data_);
EXPECT_EQ(*predictor_->origin_data_->data_cache_,
mock_tables_->origin_table_.data_);
- predictor_.reset(NULL);
+ loading_predictor_ = nullptr;
+ predictor_ = nullptr;
profile_->DestroyHistoryService();
}
@@ -624,8 +618,7 @@
content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false);
predictor_->RecordURLResponse(resource3);
- StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
- predictor_.get());
+ StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_);
EXPECT_CALL(
mock_observer,
OnNavigationLearned(kVisitCount,
@@ -724,8 +717,7 @@
predictor_->RecordURLResponse(redirected);
- StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
- predictor_.get());
+ StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_);
EXPECT_CALL(mock_observer,
OnNavigationLearned(
kVisitCount, CreatePageRequestSummary("http://www.google.com",
@@ -839,8 +831,7 @@
no_store.is_no_store = true;
predictor_->RecordURLResponse(no_store);
- StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
- predictor_.get());
+ StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_);
EXPECT_CALL(mock_observer,
OnNavigationLearned(
kVisitCount, CreatePageRequestSummary("http://www.google.com",
@@ -942,8 +933,7 @@
content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false);
predictor_->RecordURLResponse(resource2);
- StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
- predictor_.get());
+ StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_);
EXPECT_CALL(mock_observer,
OnNavigationLearned(
kVisitCount, CreatePageRequestSummary(
@@ -1013,8 +1003,7 @@
predictor_->RecordURLRedirect(fb3);
NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google");
- StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
- predictor_.get());
+ StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_);
EXPECT_CALL(
mock_observer,
OnNavigationLearned(kVisitCount, CreatePageRequestSummary(
@@ -1064,8 +1053,7 @@
predictor_->RecordURLRedirect(fb3);
NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google");
- StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(
- predictor_.get());
+ StrictMock<MockResourcePrefetchPredictorObserver> mock_observer(predictor_);
EXPECT_CALL(
mock_observer,
OnNavigationLearned(kVisitCount, CreatePageRequestSummary(
@@ -2069,28 +2057,6 @@
ResourcePrefetchPredictor::RedirectStatus::REDIRECT_CORRECTLY_PREDICTED);
}
-TEST_F(ResourcePrefetchPredictorTest, TestPrefetchingDurationHistogram) {
- // Prefetching duration for an url without resources in the database
- // shouldn't be recorded.
- const std::string main_frame_url = "http://google.com/?query=cats";
- predictor_->StartPrefetching(GURL(main_frame_url), HintOrigin::EXTERNAL);
- predictor_->StopPrefetching(GURL(main_frame_url));
- histogram_tester_->ExpectTotalCount(
- internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 0);
-
- // Fill the database to record a duration.
- PrefetchData google = CreatePrefetchData("google.com", 1);
- InitializeResourceData(
- google.add_resources(), "https://cdn.google.com/script.js",
- content::RESOURCE_TYPE_SCRIPT, 10, 0, 1, 2.1, net::MEDIUM, false, false);
- predictor_->host_resource_data_->UpdateData(google.primary_key(), google);
-
- predictor_->StartPrefetching(GURL(main_frame_url), HintOrigin::EXTERNAL);
- predictor_->StopPrefetching(GURL(main_frame_url));
- histogram_tester_->ExpectTotalCount(
- internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 1);
-}
-
TEST_F(ResourcePrefetchPredictorTest, TestRecordFirstContentfulPaint) {
auto res1_time = base::TimeTicks::FromInternalValue(1);
auto res2_time = base::TimeTicks::FromInternalValue(2);
diff --git a/chrome/browser/predictors/resource_prefetcher_manager.h b/chrome/browser/predictors/resource_prefetcher_manager.h
index 84a8ec52..52fb50273 100644
--- a/chrome/browser/predictors/resource_prefetcher_manager.h
+++ b/chrome/browser/predictors/resource_prefetcher_manager.h
@@ -63,7 +63,6 @@
private:
friend class base::RefCountedThreadSafe<ResourcePrefetcherManager>;
friend class MockResourcePrefetcherManager;
-
~ResourcePrefetcherManager() override;
ResourcePrefetchPredictor* predictor_;
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc
index fd34c47d..644fd76b 100644
--- a/chrome/browser/profiles/profile_io_data.cc
+++ b/chrome/browser/profiles/profile_io_data.cc
@@ -38,8 +38,8 @@
#include "chrome/browser/net/chrome_http_user_agent_settings.h"
#include "chrome/browser/net/chrome_network_delegate.h"
#include "chrome/browser/net/chrome_url_request_context_getter.h"
+#include "chrome/browser/net/loading_predictor_observer.h"
#include "chrome/browser/net/proxy_service_factory.h"
-#include "chrome/browser/net/resource_prefetch_predictor_observer.h"
#include "chrome/browser/policy/cloud/policy_header_service_factory.h"
#include "chrome/browser/policy/policy_helpers.h"
#include "chrome/browser/predictors/loading_predictor.h"
@@ -391,9 +391,9 @@
if (auto* loading_predictor =
predictors::LoadingPredictorFactory::GetForProfile(profile)) {
- resource_prefetch_predictor_observer_.reset(
- new chrome_browser_net::ResourcePrefetchPredictorObserver(
- loading_predictor->resource_prefetch_predictor()));
+ loading_predictor_observer_ =
+ base::MakeUnique<chrome_browser_net::LoadingPredictorObserver>(
+ loading_predictor);
}
ProtocolHandlerRegistry* protocol_handler_registry =
@@ -1100,9 +1100,9 @@
resource_context_->host_resolver_ = io_thread_globals->host_resolver.get();
resource_context_->request_context_ = main_request_context_.get();
- if (profile_params_->resource_prefetch_predictor_observer_) {
- resource_prefetch_predictor_observer_.reset(
- profile_params_->resource_prefetch_predictor_observer_.release());
+ if (profile_params_->loading_predictor_observer_) {
+ loading_predictor_observer_ =
+ std::move(profile_params_->loading_predictor_observer_);
}
#if defined(OS_CHROMEOS)
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h
index 4b14494..895fa55 100644
--- a/chrome/browser/profiles/profile_io_data.h
+++ b/chrome/browser/profiles/profile_io_data.h
@@ -51,7 +51,7 @@
}
namespace chrome_browser_net {
-class ResourcePrefetchPredictorObserver;
+class LoadingPredictorObserver;
}
namespace certificate_transparency {
@@ -204,9 +204,9 @@
return &incognito_availibility_pref_;
}
- chrome_browser_net::ResourcePrefetchPredictorObserver*
- resource_prefetch_predictor_observer() const {
- return resource_prefetch_predictor_observer_.get();
+ chrome_browser_net::LoadingPredictorObserver* loading_predictor_observer()
+ const {
+ return loading_predictor_observer_.get();
}
policy::PolicyHeaderIOHelper* policy_header_helper() const {
@@ -313,8 +313,8 @@
#if BUILDFLAG(ENABLE_EXTENSIONS)
scoped_refptr<extensions::InfoMap> extension_info_map;
#endif
- std::unique_ptr<chrome_browser_net::ResourcePrefetchPredictorObserver>
- resource_prefetch_predictor_observer_;
+ std::unique_ptr<chrome_browser_net::LoadingPredictorObserver>
+ loading_predictor_observer_;
// This pointer exists only as a means of conveying a url job factory
// pointer from the protocol handler registry on the UI thread to the
@@ -600,8 +600,8 @@
mutable scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
- mutable std::unique_ptr<chrome_browser_net::ResourcePrefetchPredictorObserver>
- resource_prefetch_predictor_observer_;
+ mutable std::unique_ptr<chrome_browser_net::LoadingPredictorObserver>
+ loading_predictor_observer_;
mutable std::unique_ptr<ChromeHttpUserAgentSettings>
chrome_http_user_agent_settings_;