Commit d10c5136 authored by Sophie Chang's avatar Sophie Chang Committed by Commit Bot

Pass down top host provider if user has appropriate permissions

Bug: 969558
Change-Id: Ia3d2240b8fb3444f1ed2f43c34a79caf6a9066ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1747136Reviewed-by: default avatarDoug Arnett <dougarnett@chromium.org>
Commit-Queue: Sophie Chang <sophiechang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686177}
parent e7e218f7
......@@ -4,12 +4,17 @@
#include "chrome/browser/data_saver/data_saver_top_host_provider.h"
#include <algorithm>
#include "base/metrics/histogram_macros.h"
#include "base/values.h"
#include "chrome/browser/engagement/site_engagement_details.mojom.h"
#include "chrome/browser/engagement/site_engagement_score.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/previews/previews_service.h"
#include "chrome/browser/previews/previews_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/optimization_guide/hints_processing_util.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/prefs/pref_service.h"
......@@ -28,8 +33,36 @@ bool IsHostBlacklisted(const base::DictionaryValue* top_host_blacklist,
optimization_guide::HashHostForDictionary(host));
}
bool IsPermittedToUseTopHostProvider(content::BrowserContext* browser_context) {
Profile* profile = Profile::FromBrowserContext(browser_context);
// Check if they are a data saver user.
if (!data_reduction_proxy::DataReductionProxySettings::
IsDataSaverEnabledByUser(profile->GetPrefs())) {
return false;
}
// Now ensure that they have seen the HTTPS infobar notification.
PreviewsService* previews_service =
PreviewsServiceFactory::GetForProfile(profile);
if (!previews_service)
return false;
PreviewsHTTPSNotificationInfoBarDecider* info_bar_decider =
previews_service->previews_https_notification_infobar_decider();
return !info_bar_decider->NeedsToNotifyUser();
}
} // namespace
// static
std::unique_ptr<DataSaverTopHostProvider>
DataSaverTopHostProvider::CreateIfAllowed(
content::BrowserContext* browser_context) {
if (IsPermittedToUseTopHostProvider(browser_context))
return std::make_unique<DataSaverTopHostProvider>(browser_context);
return nullptr;
}
DataSaverTopHostProvider::DataSaverTopHostProvider(
content::BrowserContext* browser_context)
: browser_context_(browser_context),
......
......@@ -27,9 +27,18 @@ class NavigationHandle;
// been approved for users that have Data Saver (aka Lite Mode) enabled.
class DataSaverTopHostProvider : public optimization_guide::TopHostProvider {
public:
// TODO(sophiechang): Make this constructor private when
// OptimizationGuideKeyedService is fully rolled out. All future callers
// should be using the CreateIfAllowed() factory method instead, which
// validates if the user has the proper permissions to use this class.
explicit DataSaverTopHostProvider(content::BrowserContext* BrowserContext);
~DataSaverTopHostProvider() override;
// Creates a DataSaverTopHostProvider if the user is a Data Saver user and has
// also seen the notification.
static std::unique_ptr<DataSaverTopHostProvider> CreateIfAllowed(
content::BrowserContext* browser_context);
// Update the HintsFetcherTopHostBlacklist by attempting to remove the host
// for the current navigation from the blacklist. A host is removed if it is
// currently on the blacklist and the blacklist state is updated if the
......@@ -37,6 +46,7 @@ class DataSaverTopHostProvider : public optimization_guide::TopHostProvider {
static void MaybeUpdateTopHostBlacklist(
content::NavigationHandle* navigation_handle);
// optimization_guide::TopHostProvider implementation:
std::vector<std::string> GetTopHosts(size_t max_sites) override;
private:
......
......@@ -7,13 +7,20 @@
#include "base/values.h"
#include "chrome/browser/engagement/site_engagement_score.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/previews/previews_https_notification_infobar_decider.h"
#include "chrome/browser/previews/previews_lite_page_decider.h"
#include "chrome/browser/previews/previews_service.h"
#include "chrome/browser/previews/previews_service_factory.h"
#include "chrome/browser/previews/previews_ui_tab_helper.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/optimization_guide/hints_processing_util.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/optimization_guide_prefs.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/mock_navigation_handle.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
// Class to test the TopHostProvider and the HintsFetcherTopHostBlacklist.
......@@ -25,6 +32,21 @@ class DataSaverTopHostProviderTest : public ChromeRenderViewHostTestHarness {
top_host_provider_ = std::make_unique<DataSaverTopHostProvider>(profile());
service_ = SiteEngagementService::Get(profile());
pref_service_ = profile()->GetPrefs();
drp_test_context_ =
data_reduction_proxy::DataReductionProxyTestContext::Builder()
.WithMockConfig()
.Build();
drp_test_context_->DisableWarmupURLFetch();
}
void TearDown() override {
drp_test_context_->DestroySettings();
ChromeRenderViewHostTestHarness::TearDown();
}
void SetDataSaverEnabled(bool enabled) {
drp_test_context_->SetDataReductionProxyEnabled(enabled);
}
void AddEngagedHosts(size_t num_hosts) {
......@@ -123,18 +145,56 @@ class DataSaverTopHostProviderTest : public ChromeRenderViewHostTestHarness {
kHintsFetcherDataSaverTopHostBlacklistState));
}
void TearDown() override { ChromeRenderViewHostTestHarness::TearDown(); }
DataSaverTopHostProvider* top_host_provider() {
return top_host_provider_.get();
}
private:
std::unique_ptr<DataSaverTopHostProvider> top_host_provider_;
std::unique_ptr<data_reduction_proxy::DataReductionProxyTestContext>
drp_test_context_;
SiteEngagementService* service_;
PrefService* pref_service_;
};
TEST_F(DataSaverTopHostProviderTest, CreateIfAllowedNonDataSaverUser) {
SetDataSaverEnabled(false);
ASSERT_FALSE(DataSaverTopHostProvider::CreateIfAllowed(profile()));
}
TEST_F(DataSaverTopHostProviderTest,
CreateIfAllowedDataSaverUserInfobarNotSeen) {
SetDataSaverEnabled(true);
// Make sure infobar not shown.
PreviewsService* previews_service = PreviewsServiceFactory::GetForProfile(
Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
PreviewsLitePageDecider* decider =
previews_service->previews_lite_page_decider();
// Initialize settings here so Lite Pages Decider checks for the Data Saver
// bit.
decider->OnSettingsInitialized();
EXPECT_TRUE(decider->NeedsToNotifyUser());
ASSERT_FALSE(DataSaverTopHostProvider::CreateIfAllowed(profile()));
}
TEST_F(DataSaverTopHostProviderTest, CreateIfAllowedDataSaverUserInfobarSeen) {
SetDataSaverEnabled(true);
// Navigate so infobar is shown.
PreviewsUITabHelper::CreateForWebContents(web_contents());
PreviewsService* previews_service = PreviewsServiceFactory::GetForProfile(
Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
PreviewsHTTPSNotificationInfoBarDecider* decider =
previews_service->previews_https_notification_infobar_decider();
content::WebContentsTester::For(web_contents())
->NavigateAndCommit(GURL("http://whatever.com"));
EXPECT_FALSE(decider->NeedsToNotifyUser());
ASSERT_TRUE(DataSaverTopHostProvider::CreateIfAllowed(profile()));
}
TEST_F(DataSaverTopHostProviderTest, GetTopHostsMaxSites) {
SetTopHostBlacklistState(optimization_guide::prefs::
HintsFetcherTopHostBlacklistState::kInitialized);
......
......@@ -19,9 +19,11 @@
#include "components/optimization_guide/hints_component_util.h"
#include "components/optimization_guide/hints_processing_util.h"
#include "components/optimization_guide/optimization_filter.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/optimization_guide_prefs.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/optimization_guide_switches.h"
#include "components/optimization_guide/top_host_provider.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
......@@ -76,7 +78,8 @@ OptimizationGuideHintsManager::OptimizationGuideHintsManager(
optimization_guide::OptimizationGuideService* optimization_guide_service,
const base::FilePath& profile_path,
PrefService* pref_service,
leveldb_proto::ProtoDatabaseProvider* database_provider)
leveldb_proto::ProtoDatabaseProvider* database_provider,
optimization_guide::TopHostProvider* top_host_provider)
: optimization_guide_service_(optimization_guide_service),
background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
{base::ThreadPool(), base::MayBlock(),
......@@ -87,7 +90,8 @@ OptimizationGuideHintsManager::OptimizationGuideHintsManager(
database_provider,
profile_path,
pref_service_,
background_task_runner_))) {
background_task_runner_))),
top_host_provider_(top_host_provider) {
DCHECK(optimization_guide_service_);
hint_cache_->Initialize(
optimization_guide::switches::ShouldPurgeHintCacheStoreOnStartup(),
......@@ -259,6 +263,8 @@ void OptimizationGuideHintsManager::OnHintCacheInitialized() {
UpdateComponentHints(base::DoNothing(), std::move(hint_update_data));
}
MaybeScheduleHintsFetch();
// Register as an observer regardless of hint proto override usage. This is
// needed as a signal during testing.
optimization_guide_service_->AddObserver(this);
......@@ -306,6 +312,19 @@ void OptimizationGuideHintsManager::ListenForNextUpdateForTesting(
next_update_closure_ = std::move(next_update_closure);
}
void OptimizationGuideHintsManager::MaybeScheduleHintsFetch() {
bool hints_fetching_allowed =
optimization_guide::features::IsHintsFetchingEnabled() &&
top_host_provider_;
// This local histogram is only used for testing and will be removed when the
// actual implementation to schedule hints fetches is in place.
LOCAL_HISTOGRAM_BOOLEAN("OptimizationGuide.HintsFetching.Allowed",
hints_fetching_allowed);
// TODO(crbug/969558): Implement this to actually schedule a hints fetch and
// remove above local histogram.
}
void OptimizationGuideHintsManager::LoadHintForNavigation(
content::NavigationHandle* navigation_handle,
base::OnceClosure callback) {
......
......@@ -36,6 +36,7 @@ class HintCache;
class HintUpdateData;
class OptimizationFilter;
class OptimizationGuideService;
class TopHostProvider;
} // namespace optimization_guide
class PrefService;
......@@ -47,7 +48,8 @@ class OptimizationGuideHintsManager
optimization_guide::OptimizationGuideService* optimization_guide_service,
const base::FilePath& profile_path,
PrefService* pref_service,
leveldb_proto::ProtoDatabaseProvider* database_provider);
leveldb_proto::ProtoDatabaseProvider* database_provider,
optimization_guide::TopHostProvider* top_host_provider);
~OptimizationGuideHintsManager() override;
......@@ -121,6 +123,9 @@ class OptimizationGuideHintsManager
void OnComponentHintsUpdated(base::OnceClosure update_closure,
bool hints_updated) const;
// Method to request new hints for user's sites.
void MaybeScheduleHintsFetch();
// Called when the request to load a hint has completed.
void OnHintLoaded(base::OnceClosure callback,
const optimization_guide::proto::Hint* loaded_hint) const;
......@@ -164,6 +169,9 @@ class OptimizationGuideHintsManager
// fetched from the remote Optimization Guide Service.
std::unique_ptr<optimization_guide::HintCache> hint_cache_;
// The top host provider that can be queried. Not owned.
optimization_guide::TopHostProvider* top_host_provider_ = nullptr;
// Used in testing to subscribe to an update event in this class.
base::OnceClosure next_update_closure_;
......
......@@ -10,7 +10,9 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "components/optimization_guide/bloom_filter.h"
#include "components/optimization_guide/command_line_top_host_provider.h"
#include "components/optimization_guide/hints_component_util.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/optimization_guide_prefs.h"
......@@ -96,7 +98,8 @@ class OptimizationGuideHintsManagerTest
ResetHintsManager();
}
void CreateServiceAndHintsManager() {
void CreateServiceAndHintsManager(
optimization_guide::TopHostProvider* top_host_provider = nullptr) {
if (hints_manager_) {
ResetHintsManager();
}
......@@ -108,7 +111,7 @@ class OptimizationGuideHintsManagerTest
hints_manager_ = std::make_unique<OptimizationGuideHintsManager>(
optimization_guide_service_.get(), temp_dir(), pref_service_.get(),
db_provider_.get());
db_provider_.get(), top_host_provider);
// Add observer is called after the HintCache is fully initialized,
// indicating that the OptimizationGuideHintsManager is ready to process
......@@ -701,3 +704,53 @@ TEST_F(OptimizationGuideHintsManagerTest, InvalidOptimizationFilterNotLoaded) {
EXPECT_FALSE(hints_manager()->HasLoadedOptimizationFilter(
optimization_guide::proto::LITE_PAGE_REDIRECT));
}
TEST_F(OptimizationGuideHintsManagerTest,
HintsFetchNotAllowedIfFeatureIsEnabledButTopHostProviderIsNotProvided) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{optimization_guide::features::kOptimizationHintsFetching}, {});
base::HistogramTester histogram_tester;
CreateServiceAndHintsManager(/*top_host_provider=*/nullptr);
histogram_tester.ExpectUniqueSample("OptimizationGuide.HintsFetching.Allowed",
false, 1);
}
TEST_F(OptimizationGuideHintsManagerTest,
HintsFetchNotAllowedIfFeatureIsNotEnabledButTopHostProviderIsProvided) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
optimization_guide::switches::kFetchHintsOverride, "whatever.com");
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{}, {optimization_guide::features::kOptimizationHintsFetching});
base::HistogramTester histogram_tester;
std::unique_ptr<optimization_guide::TopHostProvider> top_host_provider =
optimization_guide::CommandLineTopHostProvider::CreateIfEnabled();
CreateServiceAndHintsManager(top_host_provider.get());
histogram_tester.ExpectUniqueSample("OptimizationGuide.HintsFetching.Allowed",
false, 1);
}
TEST_F(OptimizationGuideHintsManagerTest,
HintsFetchAllowedIfFeatureIsEnabledAndTopHostProviderIsProvided) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
optimization_guide::switches::kFetchHintsOverride, "whatever.com");
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{optimization_guide::features::kOptimizationHintsFetching}, {});
base::HistogramTester histogram_tester;
std::unique_ptr<optimization_guide::TopHostProvider> top_host_provider =
optimization_guide::CommandLineTopHostProvider::CreateIfEnabled();
CreateServiceAndHintsManager(top_host_provider.get());
histogram_tester.ExpectUniqueSample("OptimizationGuide.HintsFetching.Allowed",
true, 1);
}
......@@ -6,14 +6,38 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "chrome/browser/data_saver/data_saver_top_host_provider.h"
#include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "components/leveldb_proto/public/proto_database_provider.h"
#include "components/optimization_guide/command_line_top_host_provider.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/top_host_provider.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
namespace {
// Returns the top host provider to be used with this keyed service. Can return
// nullptr if the user or browser is not permitted to call the remote
// Optimization Guide Service.
std::unique_ptr<optimization_guide::TopHostProvider>
GetTopHostProviderIfUserPermitted(content::BrowserContext* browser_context) {
// First check whether the command-line flag should be used.
std::unique_ptr<optimization_guide::TopHostProvider> top_host_provider =
optimization_guide::CommandLineTopHostProvider::CreateIfEnabled();
if (top_host_provider)
return top_host_provider;
// If not enabled by flag, see if the user is a Data Saver user and has seen
// all the right prompts for it.
return DataSaverTopHostProvider::CreateIfAllowed(browser_context);
}
} // namespace
OptimizationGuideKeyedService::OptimizationGuideKeyedService(
content::BrowserContext* browser_context)
: browser_context_(browser_context) {
......@@ -32,10 +56,11 @@ void OptimizationGuideKeyedService::Initialize(
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(optimization_guide_service);
top_host_provider_ = GetTopHostProviderIfUserPermitted(browser_context_);
hints_manager_ = std::make_unique<OptimizationGuideHintsManager>(
optimization_guide_service, profile_path,
Profile::FromBrowserContext(browser_context_)->GetPrefs(),
database_provider);
database_provider, top_host_provider_.get());
}
void OptimizationGuideKeyedService::RegisterOptimizationTypes(
......
......@@ -28,6 +28,7 @@ class ProtoDatabaseProvider;
namespace optimization_guide {
class OptimizationGuideService;
class TopHostProvider;
} // namespace optimization_guide
class OptimizationGuideHintsManager;
......@@ -50,6 +51,10 @@ class OptimizationGuideKeyedService : public KeyedService {
return hints_manager_.get();
}
optimization_guide::TopHostProvider* GetTopHostProvider() {
return top_host_provider_.get();
}
// Registers the optimization types that intend to be queried during the
// session.
void RegisterOptimizationTypes(
......@@ -64,12 +69,15 @@ class OptimizationGuideKeyedService : public KeyedService {
void Shutdown() override;
private:
std::unique_ptr<OptimizationGuideHintsManager> hints_manager_;
content::BrowserContext* browser_context_;
std::unordered_set<optimization_guide::proto::OptimizationType>
registered_optimization_types_;
// Manages the storing, loading, and fetching of hints.
std::unique_ptr<OptimizationGuideHintsManager> hints_manager_;
content::BrowserContext* browser_context_;
// The top host provider to use for fetching information for the user's top
// hosts. Will be null if the user has not consented to this type of browser
// behavior.
std::unique_ptr<optimization_guide::TopHostProvider> top_host_provider_;
DISALLOW_COPY_AND_ASSIGN(OptimizationGuideKeyedService);
};
......
......@@ -6,6 +6,8 @@
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/data_saver/data_saver_top_host_provider.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
......@@ -13,9 +15,14 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/optimization_guide/command_line_top_host_provider.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/optimization_guide_prefs.h"
#include "components/optimization_guide/optimization_guide_switches.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/optimization_guide/test_hints_component_creator.h"
#include "components/prefs/pref_service.h"
#include "components/previews/core/previews_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
......@@ -150,6 +157,13 @@ class OptimizationGuideKeyedServiceBrowserTest
DISALLOW_COPY_AND_ASSIGN(OptimizationGuideKeyedServiceBrowserTest);
};
IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceBrowserTest,
TopHostProviderNotSetIfNotAllowed) {
ASSERT_FALSE(
OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
->GetTopHostProvider());
}
IN_PROC_BROWSER_TEST_F(
OptimizationGuideKeyedServiceBrowserTest,
NavigateToPageWithHintsButNoRegistrationDoesNotAttemptToLoadHint) {
......@@ -214,3 +228,100 @@ IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceBrowserTest,
histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result",
false, 1);
}
class OptimizationGuideKeyedServiceDataSaverUserWithInfobarShownTest
: public OptimizationGuideKeyedServiceBrowserTest {
public:
OptimizationGuideKeyedServiceDataSaverUserWithInfobarShownTest() = default;
~OptimizationGuideKeyedServiceDataSaverUserWithInfobarShownTest() override =
default;
void SetUpOnMainThread() override {
OptimizationGuideKeyedServiceBrowserTest::SetUpOnMainThread();
SeedSiteEngagementService();
// Set the blacklist state to initialized so the sites in the engagement
// service will be used and not blacklisted on the first GetTopHosts
// request.
InitializeDataSaverTopHostBlacklist();
}
void SetUpCommandLine(base::CommandLine* cmd) override {
cmd->AppendSwitch("enable-spdy-proxy-auth");
// Add switch to avoid having to see the infobar in the test.
cmd->AppendSwitch(previews::switches::kDoNotRequireLitePageRedirectInfoBar);
}
private:
// Seeds the Site Engagement Service with two HTTP and two HTTPS sites for the
// current profile.
void SeedSiteEngagementService() {
SiteEngagementService* service = SiteEngagementService::Get(
Profile::FromBrowserContext(browser()
->tab_strip_model()
->GetActiveWebContents()
->GetBrowserContext()));
GURL https_url1("https://myfavoritesite.com/");
service->AddPointsForTesting(https_url1, 15);
GURL https_url2("https://myotherfavoritesite.com/");
service->AddPointsForTesting(https_url2, 3);
}
void InitializeDataSaverTopHostBlacklist() {
Profile::FromBrowserContext(browser()
->tab_strip_model()
->GetActiveWebContents()
->GetBrowserContext())
->GetPrefs()
->SetInteger(optimization_guide::prefs::
kHintsFetcherDataSaverTopHostBlacklistState,
static_cast<int>(
optimization_guide::prefs::
HintsFetcherTopHostBlacklistState::kInitialized));
}
};
IN_PROC_BROWSER_TEST_F(
OptimizationGuideKeyedServiceDataSaverUserWithInfobarShownTest,
TopHostProviderIsSentDown) {
OptimizationGuideKeyedService* keyed_service =
OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile());
optimization_guide::TopHostProvider* top_host_provider =
keyed_service->GetTopHostProvider();
ASSERT_TRUE(top_host_provider);
std::vector<std::string> top_hosts = top_host_provider->GetTopHosts(1);
EXPECT_EQ(1ul, top_hosts.size());
EXPECT_EQ("myfavoritesite.com", top_hosts[0]);
}
class OptimizationGuideKeyedServiceCommandLineOverridesTest
: public OptimizationGuideKeyedServiceDataSaverUserWithInfobarShownTest {
public:
OptimizationGuideKeyedServiceCommandLineOverridesTest() = default;
~OptimizationGuideKeyedServiceCommandLineOverridesTest() override = default;
void SetUpCommandLine(base::CommandLine* cmd) override {
OptimizationGuideKeyedServiceDataSaverUserWithInfobarShownTest::
SetUpCommandLine(cmd);
cmd->AppendSwitchASCII(optimization_guide::switches::kFetchHintsOverride,
"whatever.com,awesome.com");
}
};
IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceCommandLineOverridesTest,
TopHostProviderIsSentDown) {
OptimizationGuideKeyedService* keyed_service =
OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile());
optimization_guide::TopHostProvider* top_host_provider =
keyed_service->GetTopHostProvider();
ASSERT_TRUE(top_host_provider);
std::vector<std::string> top_hosts = top_host_provider->GetTopHosts(1);
EXPECT_EQ(1ul, top_hosts.size());
EXPECT_EQ("whatever.com", top_hosts[0]);
}
......@@ -8,6 +8,8 @@ static_library("optimization_guide") {
sources = [
"bloom_filter.cc",
"bloom_filter.h",
"command_line_top_host_provider.cc",
"command_line_top_host_provider.h",
"hint_cache.cc",
"hint_cache.h",
"hint_cache_store.cc",
......@@ -78,6 +80,7 @@ source_set("unit_tests") {
testonly = true
sources = [
"bloom_filter_unittest.cc",
"command_line_top_host_provider_unittest.cc",
"hint_cache_store_unittest.cc",
"hint_cache_unittest.cc",
"hint_update_data_unittest.cc",
......
// Copyright 2019 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 "components/optimization_guide/command_line_top_host_provider.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "components/optimization_guide/optimization_guide_switches.h"
namespace optimization_guide {
// static
std::unique_ptr<CommandLineTopHostProvider>
CommandLineTopHostProvider::CreateIfEnabled() {
base::Optional<std::vector<std::string>> top_hosts =
switches::ParseHintsFetchOverrideFromCommandLine();
if (top_hosts) {
// Note: wrap_unique is used because the constructor is private.
return base::WrapUnique(new CommandLineTopHostProvider(*top_hosts));
}
return nullptr;
}
CommandLineTopHostProvider::CommandLineTopHostProvider(
const std::vector<std::string>& top_hosts)
: top_hosts_(top_hosts) {}
CommandLineTopHostProvider::~CommandLineTopHostProvider() = default;
std::vector<std::string> CommandLineTopHostProvider::GetTopHosts(
size_t max_sites) {
if (top_hosts_.size() <= max_sites) {
return top_hosts_;
}
std::vector<std::string> top_hosts;
top_hosts.reserve(max_sites);
for (const auto& top_host : top_hosts_) {
if (top_hosts.size() >= max_sites)
return top_hosts;
top_hosts.push_back(top_host);
}
return top_hosts;
}
} // namespace optimization_guide
// Copyright 2019 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 COMPONENTS_OPTIMIZATION_GUIDE_COMMAND_LINE_TOP_HOST_PROVIDER_H_
#define COMPONENTS_OPTIMIZATION_GUIDE_COMMAND_LINE_TOP_HOST_PROVIDER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "components/optimization_guide/top_host_provider.h"
namespace optimization_guide {
// A TopHostProvider implementation that provides top hosts based on what is fed
// through the command line. This implementation is intended to be used just for
// developer and integration testing.
class CommandLineTopHostProvider : public TopHostProvider {
public:
// Creates a TopHostProvider if the flag for overriding top hosts has been
// enabled.
static std::unique_ptr<CommandLineTopHostProvider> CreateIfEnabled();
~CommandLineTopHostProvider() override;
// TopHostProvider implementation:
std::vector<std::string> GetTopHosts(size_t max_sites) override;
private:
explicit CommandLineTopHostProvider(
const std::vector<std::string>& top_hosts);
std::vector<std::string> top_hosts_;
DISALLOW_COPY_AND_ASSIGN(CommandLineTopHostProvider);
};
} // namespace optimization_guide
#endif // COMPONENTS_OPTIMIZATION_GUIDE_COMMAND_LINE_TOP_HOST_PROVIDER_H_
// Copyright 2019 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 "components/optimization_guide/command_line_top_host_provider.h"
#include "base/command_line.h"
#include "components/optimization_guide/optimization_guide_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace optimization_guide {
TEST(CommandLineTopHostProviderTest, DoesNotCreateIfFlagNotEnabled) {
ASSERT_FALSE(CommandLineTopHostProvider::CreateIfEnabled());
}
TEST(CommandLineTopHostProviderTest, DoesNotCreateIfSwitchEnabledButNoHosts) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kFetchHintsOverride);
ASSERT_FALSE(CommandLineTopHostProvider::CreateIfEnabled());
}
TEST(CommandLineTopHostProviderTest, CreateIfFlagEnabledAndHasHosts) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kFetchHintsOverride, "whatever.com");
std::unique_ptr<CommandLineTopHostProvider> top_host_provider =
CommandLineTopHostProvider::CreateIfEnabled();
ASSERT_TRUE(top_host_provider);
}
TEST(CommandLineTopHostProviderTest,
GetTopHostsMaxLessThanProvidedSizeReturnsEverything) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kFetchHintsOverride, "whatever.com");
std::unique_ptr<CommandLineTopHostProvider> top_host_provider =
CommandLineTopHostProvider::CreateIfEnabled();
ASSERT_TRUE(top_host_provider);
std::vector<std::string> top_hosts =
top_host_provider->GetTopHosts(/*max_size=*/2);
EXPECT_EQ(1ul, top_hosts.size());
EXPECT_EQ("whatever.com", top_hosts[0]);
}
TEST(CommandLineTopHostProviderTest,
GetTopHostsMaxGreaterThanTotalVectorSizeReturnsFirstN) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kFetchHintsOverride, "whatever.com,awesome.com");
std::unique_ptr<CommandLineTopHostProvider> top_host_provider =
CommandLineTopHostProvider::CreateIfEnabled();
ASSERT_TRUE(top_host_provider);
std::vector<std::string> top_hosts =
top_host_provider->GetTopHosts(/*max_size=*/1);
EXPECT_EQ(1ul, top_hosts.size());
EXPECT_EQ("whatever.com", top_hosts[0]);
}
} // namespace optimization_guide
......@@ -13,13 +13,14 @@ namespace optimization_guide {
// A class to handle querying for the top hosts for a user.
class TopHostProvider {
public:
virtual ~TopHostProvider() {}
// Returns a vector of at most |max_sites| top hosts, the order of hosts is
// not guaranteed.
virtual std::vector<std::string> GetTopHosts(size_t max_sites) = 0;
protected:
TopHostProvider() {}
virtual ~TopHostProvider() {}
};
} // namespace optimization_guide
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment