Commit 576056af authored by Michael Crouse's avatar Michael Crouse Committed by Commit Bot

Adding feature flag for enabling OnePlatform API hints and

created a Top Site Provider for querying SiteEngagementService

Implemented a feature flag controlled by IsOnePlatformHintsEnabled()
for enabling OnePlatform API and requests.

Implemented the Top Site Provider inference and implementation for
querying the Site Engagement Service to provide the list of top hosts
for the OnePlatform to perform the Hints Request to the Cacao server.

Updated the unittests for Previews Optimization Guide and Previews
Decider Impl to include the TopSiteProvider being passed.

Wrote a PreviewsOnePlatformHintBrowserTest for confirming the feature
flag and code path is executed safely.


Bug: 932707
Change-Id: I2d1a048a86e8c8b33c98c07312cc77bafa9b52dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1478362
Commit-Queue: Michael Crouse <mcrouse@chromium.org>
Auto-Submit: Michael Crouse <mcrouse@chromium.org>
Reviewed-by: default avatarTarun Bansal <tbansal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638654}
parent 1198ba3a
...@@ -1322,6 +1322,8 @@ jumbo_split_static_library("browser") { ...@@ -1322,6 +1322,8 @@ jumbo_split_static_library("browser") {
"previews/previews_service.h", "previews/previews_service.h",
"previews/previews_service_factory.cc", "previews/previews_service_factory.cc",
"previews/previews_service_factory.h", "previews/previews_service_factory.h",
"previews/previews_top_host_provider_impl.cc",
"previews/previews_top_host_provider_impl.h",
"previews/previews_ui_tab_helper.cc", "previews/previews_ui_tab_helper.cc",
"previews/previews_ui_tab_helper.h", "previews/previews_ui_tab_helper.h",
"previews/resource_loading_hints/resource_loading_hints_web_contents_observer.cc", "previews/resource_loading_hints/resource_loading_hints_web_contents_observer.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 <map>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/subprocess_metrics_provider.h"
#include "chrome/browser/previews/previews_service.h"
#include "chrome/browser/previews/previews_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#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/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/optimization_guide/hints_component_info.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/optimization_guide/test_hints_component_creator.h"
#include "components/previews/content/previews_decider_impl.h"
#include "components/previews/content/previews_optimization_guide.h"
#include "components/previews/content/previews_ui_service.h"
#include "components/previews/core/previews_black_list.h"
#include "components/previews/core/previews_constants.h"
#include "components/previews/core/previews_features.h"
#include "components/previews/core/previews_switches.h"
#include "content/public/browser/browser_task_traits.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"
#include "services/network/public/cpp/network_quality_tracker.h"
namespace {
// Fetch and calculate the total number of samples from all the bins for
// |histogram_name|. Note: from some browertests run (such as chromeos) there
// might be two profiles created, and this will return the total sample count
// across profiles.
int GetTotalHistogramSamples(const base::HistogramTester* histogram_tester,
const std::string& histogram_name) {
std::vector<base::Bucket> buckets =
histogram_tester->GetAllSamples(histogram_name);
int total = 0;
for (const auto& bucket : buckets)
total += bucket.count;
return total;
}
// Retries fetching |histogram_name| until it contains at least |count| samples.
int RetryForHistogramUntilCountReached(
const base::HistogramTester* histogram_tester,
const std::string& histogram_name,
int count) {
int total = 0;
while (true) {
base::TaskScheduler::GetInstance()->FlushForTesting();
base::RunLoop().RunUntilIdle();
total = GetTotalHistogramSamples(histogram_tester, histogram_name);
if (total >= count)
return total;
}
}
} // namespace
// This test class sets up everything but does not enable any features.
class PreviewsOnePlatformNoFeaturesBrowserTest : public InProcessBrowserTest {
public:
PreviewsOnePlatformNoFeaturesBrowserTest() = default;
~PreviewsOnePlatformNoFeaturesBrowserTest() override = default;
void SetUpOnMainThread() override {
https_server_.reset(
new net::EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS));
https_server_->ServeFilesFromSourceDirectory("chrome/test/data/previews");
ASSERT_TRUE(https_server_->Start());
InProcessBrowserTest::SetUpOnMainThread();
}
void SetUpCommandLine(base::CommandLine* cmd) override {
cmd->AppendSwitch("enable-spdy-proxy-auth");
// Due to race conditions, it's possible that blacklist data is not loaded
// at the time of first navigation. That may prevent Preview from
// triggering, and causing the test to flake.
cmd->AppendSwitch(previews::switches::kIgnorePreviewsBlacklist);
}
const GURL& https_url() const { return https_url_; }
const base::HistogramTester* GetHistogramTester() {
return &histogram_tester_;
}
protected:
base::test::ScopedFeatureList scoped_feature_list_;
private:
void TearDownOnMainThread() override {
EXPECT_TRUE(https_server_->ShutdownAndWaitUntilComplete());
InProcessBrowserTest::TearDownOnMainThread();
}
std::unique_ptr<net::EmbeddedTestServer> https_server_;
GURL https_url_;
base::HistogramTester histogram_tester_;
DISALLOW_COPY_AND_ASSIGN(PreviewsOnePlatformNoFeaturesBrowserTest);
};
// This test class enables OnePlatform Hints.
class PreviewsOnePlatformHintsBrowserTest
: public PreviewsOnePlatformNoFeaturesBrowserTest {
public:
PreviewsOnePlatformHintsBrowserTest() = default;
~PreviewsOnePlatformHintsBrowserTest() override = default;
void SetUp() override {
// Enabled OnePlatformHints with |kPreviewsOnePlatformHints|.
scoped_feature_list_.InitWithFeatures(
{previews::features::kPreviews, previews::features::kOptimizationHints,
previews::features::kPreviewsOnePlatformHints},
{});
// Call to inherited class to match same set up with feature flags added.
PreviewsOnePlatformNoFeaturesBrowserTest::SetUp();
}
private:
DISALLOW_COPY_AND_ASSIGN(PreviewsOnePlatformHintsBrowserTest);
};
// This test creates new browser with no profile and loads a random page with
// the feature flags enables the PreviewsOnePlatformHints. We confirm that the
// top_host_provider_impl executes and does not crash by checking UMA
// histograms for the total number of TopEngagementSites and
// the total number of sites returned controlled by the experiments flag
// |max_oneplatform_update_hosts|.
IN_PROC_BROWSER_TEST_F(PreviewsOnePlatformHintsBrowserTest,
OnePlatformHintsEnabled) {
const base::HistogramTester* histogram_tester = GetHistogramTester();
// Expect that the browser initialization will record at least one sample
// in each of the follow histograms as One Platform Hints are enabled.
EXPECT_GE(RetryForHistogramUntilCountReached(
histogram_tester,
"Previews.HintsFetcher.GetHintsRequest.HostCount", 1),
1);
}
IN_PROC_BROWSER_TEST_F(PreviewsOnePlatformNoFeaturesBrowserTest,
OnePlatformNoFeatures) {
const base::HistogramTester* histogram_tester = GetHistogramTester();
// Expect that the histogram for HintsFetcher to be 0 because the OnePlatform
// is not enabled.
histogram_tester->ExpectTotalCount(
"Previews.HintsFetcher.GetHintsRequest.HostCount", 0);
}
...@@ -102,7 +102,10 @@ PreviewsService::GetAllowedPreviews() { ...@@ -102,7 +102,10 @@ PreviewsService::GetAllowedPreviews() {
} }
PreviewsService::PreviewsService(content::BrowserContext* browser_context) PreviewsService::PreviewsService(content::BrowserContext* browser_context)
: previews_lite_page_decider_( : previews_top_host_provider_(
std::make_unique<previews::PreviewsTopHostProviderImpl>(
browser_context)),
previews_lite_page_decider_(
std::make_unique<PreviewsLitePageDecider>(browser_context)) { std::make_unique<PreviewsLitePageDecider>(browser_context)) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
} }
...@@ -133,7 +136,8 @@ void PreviewsService::Initialize( ...@@ -133,7 +136,8 @@ void PreviewsService::Initialize(
profile_path.Append(chrome::kPreviewsOptOutDBFilename)), profile_path.Append(chrome::kPreviewsOptOutDBFilename)),
optimization_guide_service optimization_guide_service
? std::make_unique<previews::PreviewsOptimizationGuide>( ? std::make_unique<previews::PreviewsOptimizationGuide>(
optimization_guide_service, ui_task_runner, profile_path) optimization_guide_service, ui_task_runner, profile_path,
previews_top_host_provider_.get())
: nullptr, : nullptr,
base::Bind(&IsPreviewsTypeEnabled), base::Bind(&IsPreviewsTypeEnabled),
std::make_unique<previews::PreviewsLogger>(), GetAllowedPreviews(), std::make_unique<previews::PreviewsLogger>(), GetAllowedPreviews(),
......
...@@ -6,10 +6,13 @@ ...@@ -6,10 +6,13 @@
#define CHROME_BROWSER_PREVIEWS_PREVIEWS_SERVICE_H_ #define CHROME_BROWSER_PREVIEWS_PREVIEWS_SERVICE_H_
#include <memory> #include <memory>
#include <string>
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "chrome/browser/previews/previews_top_host_provider_impl.h"
#include "components/blacklist/opt_out_blacklist/opt_out_blacklist_data.h" #include "components/blacklist/opt_out_blacklist/opt_out_blacklist_data.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
...@@ -26,6 +29,7 @@ class OptimizationGuideService; ...@@ -26,6 +29,7 @@ class OptimizationGuideService;
} }
namespace previews { namespace previews {
class PreviewsTopHostProviderImpl;
class PreviewsUIService; class PreviewsUIService;
} }
...@@ -69,6 +73,10 @@ class PreviewsService : public KeyedService { ...@@ -69,6 +73,10 @@ class PreviewsService : public KeyedService {
static blacklist::BlacklistData::AllowedTypesAndVersions GetAllowedPreviews(); static blacklist::BlacklistData::AllowedTypesAndVersions GetAllowedPreviews();
private: private:
// The top site provider for use with previews.
std::unique_ptr<previews::PreviewsTopHostProviderImpl>
previews_top_host_provider_;
// The previews UI thread service. // The previews UI thread service.
std::unique_ptr<previews::PreviewsUIService> previews_ui_service_; std::unique_ptr<previews::PreviewsUIService> previews_ui_service_;
......
// 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 "chrome/browser/previews/previews_top_host_provider_impl.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/engagement/site_engagement_details.mojom.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
namespace previews {
PreviewsTopHostProviderImpl::PreviewsTopHostProviderImpl(
content::BrowserContext* browser_context)
: browser_context_(browser_context) {}
PreviewsTopHostProviderImpl::~PreviewsTopHostProviderImpl() {}
std::vector<std::string> PreviewsTopHostProviderImpl::GetTopHosts(
size_t max_sites) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(browser_context_);
std::vector<std::string> top_hosts;
top_hosts.reserve(max_sites);
// Create SiteEngagementService to request site engagement scores.
Profile* profile = Profile::FromBrowserContext(browser_context_);
SiteEngagementService* engagement_service =
SiteEngagementService::Get(profile);
// Create a vector of the top hosts by engagement score up to |max_sites|
// size. Currently utilizes just the first |max_sites| entries.
// TODO(crbug.com/932707): Select TOP HTTPS hosts from site engagement.
std::vector<mojom::SiteEngagementDetails> engagement_details =
engagement_service->GetAllDetails();
for (const auto& detail : engagement_details) {
if (top_hosts.size() <= max_sites)
top_hosts.push_back(detail.origin.host());
else
break;
}
return top_hosts;
}
} // namespace previews
// 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 CHROME_BROWSER_PREVIEWS_PREVIEWS_TOP_HOST_PROVIDER_IMPL_H_
#define CHROME_BROWSER_PREVIEWS_PREVIEWS_TOP_HOST_PROVIDER_IMPL_H_
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "components/previews/content/previews_top_host_provider.h"
namespace content {
class BrowserContext;
}
namespace previews {
// An implementation of the PreviewTopHostProvider for getting the top sites
// based on site engagement scores.
class PreviewsTopHostProviderImpl : public PreviewsTopHostProvider {
public:
explicit PreviewsTopHostProviderImpl(content::BrowserContext* BrowserContext);
~PreviewsTopHostProviderImpl() override;
std::vector<std::string> GetTopHosts(size_t max_sites) const override;
private:
// |browser_context_| is used for interaction with the SiteEngagementService
// and the embedder should guarantee that it is non-null during the lifetime
// of |this|.
content::BrowserContext* browser_context_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(PreviewsTopHostProviderImpl);
};
} // namespace previews
#endif // CHROME_BROWSER_PREVIEWS_PREVIEWS_TOP_HOST_PROVIDER_IMPL_H_
...@@ -831,6 +831,7 @@ test("browser_tests") { ...@@ -831,6 +831,7 @@ test("browser_tests") {
"../browser/previews/lazyload_browsertest.cc", "../browser/previews/lazyload_browsertest.cc",
"../browser/previews/previews_browsertest.cc", "../browser/previews/previews_browsertest.cc",
"../browser/previews/previews_lite_page_browsertest.cc", "../browser/previews/previews_lite_page_browsertest.cc",
"../browser/previews/previews_oneplatform_hints_browsertest.cc",
"../browser/previews/previews_service_browser_test.cc", "../browser/previews/previews_service_browser_test.cc",
"../browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc", "../browser/previews/resource_loading_hints/resource_loading_hints_browsertest.cc",
"../browser/process_singleton_browsertest.cc", "../browser/process_singleton_browsertest.cc",
......
...@@ -7,6 +7,103 @@ option optimize_for = LITE_RUNTIME; ...@@ -7,6 +7,103 @@ option optimize_for = LITE_RUNTIME;
package optimization_guide.proto; package optimization_guide.proto;
// Information about the hint that the client already has for a host.
message MatchedHintInfo {
// Describes the granularity of the key field.
optional KeyRepresentation key_representation = 1;
// The key of the hint currently used for the host.
optional string key = 2;
// The version of the hint for this key already stored on the client.
optional int64 version = 3;
}
message HostInfo {
// Host that the client is requesting information for.
optional string host = 1;
// Information about the hint that the client already has for the host.
optional MatchedHintInfo matched_hint = 2;
}
// Request to return a set of hints that guide what optimizations to perform
// on those hosts.
message GetHintsRequest {
// Information about the set of hosts to retrieve hints for.
repeated HostInfo hosts = 1;
// The set of optimization types that the requesting client can support
// and perform.
//
// It is guaranteed that the response will only contain hints for
// optimizations present in this set.
repeated OptimizationType supported_optimizations = 2;
// Context in which this request is made.
optional RequestContext context = 3;
}
// Response to the GetHints request.
message GetHintsResponse {
// An ordered list containing hints for key/optimization combinations.
//
// It is guaranteed that there will only be a single hint per key and key
// representation combination. These hints are intended to apply to a full
// page. It is expected that the client will use the Hint record with the
// most specific key that matches the main frame URL.
//
// Note, this list may contain multiple hints that apply to a page. For
// example, if there are hints for (HOST_SUFFIX,cnn.com) and
// (HOST_SUFFIX,sports.cnn.com), these may both apply to
// sports.cnn.com/foo. In this case, the client is expected to use the
// hints from (HOST_SUFFIX,sports.cnn.com).
repeated Hint hints = 1;
// The maximum duration in which the hints provided in this response should
// be retained in the client cache.
optional Duration max_cache_duration = 2;
// A set of hint keys to remove from the client cache.
//
// It is guaranteed that all entries in this list were provided by the client
// in the corresponding request's |hosts.matched_hint| fields.
//
// It is expected for the client to immediately stop using all hints contained
// in this field. Hints that are not present in |hints| or in this field
// should adhere to the client cache's existing expiration policy.
repeated MatchedHintInfo hints_to_remove = 3;
}
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
// This is local definition matching server side duration.proto definition.
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
optional int64 seconds = 1;
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
optional int32 nanos = 2;
}
// Context in which the hints are requested.
enum RequestContext {
reserved 1;
// Context not specified.
CONTEXT_UNSPECIFIED = 0;
// Requesting hints on page navigation.
CONTEXT_PAGE_NAVIGATION = 2;
// Requesting hints as part of a batch update.
CONTEXT_BATCH_UPDATE = 3;
}
enum OptimizationType { enum OptimizationType {
TYPE_UNSPECIFIED = 0; TYPE_UNSPECIFIED = 0;
// This optimization blocks JavaScript on the page. // This optimization blocks JavaScript on the page.
......
...@@ -17,6 +17,7 @@ static_library("content") { ...@@ -17,6 +17,7 @@ static_library("content") {
"previews_hints_util.h", "previews_hints_util.h",
"previews_optimization_guide.cc", "previews_optimization_guide.cc",
"previews_optimization_guide.h", "previews_optimization_guide.h",
"previews_top_host_provider.h",
"previews_ui_service.cc", "previews_ui_service.cc",
"previews_ui_service.h", "previews_ui_service.h",
"previews_user_data.cc", "previews_user_data.cc",
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "components/blacklist/opt_out_blacklist/opt_out_blacklist_item.h" #include "components/blacklist/opt_out_blacklist/opt_out_blacklist_item.h"
#include "components/blacklist/opt_out_blacklist/opt_out_store.h" #include "components/blacklist/opt_out_blacklist/opt_out_store.h"
#include "components/optimization_guide/optimization_guide_service.h" #include "components/optimization_guide/optimization_guide_service.h"
#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_ui_service.h" #include "components/previews/content/previews_ui_service.h"
#include "components/previews/content/previews_user_data.h" #include "components/previews/content/previews_user_data.h"
#include "components/previews/core/previews_black_list.h" #include "components/previews/core/previews_black_list.h"
...@@ -129,6 +130,17 @@ class TestPreviewsBlackList : public PreviewsBlackList { ...@@ -129,6 +130,17 @@ class TestPreviewsBlackList : public PreviewsBlackList {
PreviewsEligibilityReason status_; PreviewsEligibilityReason status_;
}; };
// A test class implementation to enable testing of previews_decider_impl.
class TestPreviewsTopHostProvider : public PreviewsTopHostProvider {
public:
TestPreviewsTopHostProvider() {}
~TestPreviewsTopHostProvider() override {}
std::vector<std::string> GetTopHosts(size_t max_sites) const override {
return std::vector<std::string>();
}
};
// Stub class of PreviewsOptimizationGuide to control IsWhitelisted and // Stub class of PreviewsOptimizationGuide to control IsWhitelisted and
// IsBlacklisted outcomes when testing PreviewsDeciderImpl. // IsBlacklisted outcomes when testing PreviewsDeciderImpl.
class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide { class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide {
...@@ -136,10 +148,12 @@ class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide { ...@@ -136,10 +148,12 @@ class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide {
TestPreviewsOptimizationGuide( TestPreviewsOptimizationGuide(
optimization_guide::OptimizationGuideService* optimization_guide_service, optimization_guide::OptimizationGuideService* optimization_guide_service,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
const base::FilePath& test_path) const base::FilePath& test_path,
PreviewsTopHostProvider* previews_top_host_provider)
: PreviewsOptimizationGuide(optimization_guide_service, : PreviewsOptimizationGuide(optimization_guide_service,
ui_task_runner, ui_task_runner,
test_path) {} test_path,
previews_top_host_provider) {}
~TestPreviewsOptimizationGuide() override {} ~TestPreviewsOptimizationGuide() override {}
// PreviewsOptimizationGuide: // PreviewsOptimizationGuide:
...@@ -383,7 +397,7 @@ class PreviewsDeciderImplTest : public testing::Test { ...@@ -383,7 +397,7 @@ class PreviewsDeciderImplTest : public testing::Test {
std::make_unique<TestPreviewsOptimizationGuide>( std::make_unique<TestPreviewsOptimizationGuide>(
&optimization_guide_service_, &optimization_guide_service_,
scoped_task_environment_.GetMainThreadTaskRunner(), scoped_task_environment_.GetMainThreadTaskRunner(),
temp_dir_.GetPath()), temp_dir_.GetPath(), &previews_top_host_provider_),
base::BindRepeating(&IsPreviewFieldTrialEnabled), base::BindRepeating(&IsPreviewFieldTrialEnabled),
std::make_unique<PreviewsLogger>(), std::move(allowed_types), std::make_unique<PreviewsLogger>(), std::move(allowed_types),
&network_quality_tracker_)); &network_quality_tracker_));
...@@ -416,6 +430,7 @@ class PreviewsDeciderImplTest : public testing::Test { ...@@ -416,6 +430,7 @@ class PreviewsDeciderImplTest : public testing::Test {
base::FieldTrialList field_trial_list_; base::FieldTrialList field_trial_list_;
TestPreviewsDeciderImpl* previews_decider_impl_; TestPreviewsDeciderImpl* previews_decider_impl_;
optimization_guide::OptimizationGuideService optimization_guide_service_; optimization_guide::OptimizationGuideService optimization_guide_service_;
TestPreviewsTopHostProvider previews_top_host_provider_;
std::unique_ptr<TestPreviewsUIService> ui_service_; std::unique_ptr<TestPreviewsUIService> ui_service_;
network::TestNetworkQualityTracker network_quality_tracker_; network::TestNetworkQualityTracker network_quality_tracker_;
}; };
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros_local.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "components/optimization_guide/hints_component_info.h" #include "components/optimization_guide/hints_component_info.h"
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "components/previews/content/hint_cache_leveldb_store.h" #include "components/previews/content/hint_cache_leveldb_store.h"
#include "components/previews/content/previews_hints.h" #include "components/previews/content/previews_hints.h"
#include "components/previews/content/previews_hints_util.h" #include "components/previews/content/previews_hints_util.h"
#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_user_data.h" #include "components/previews/content/previews_user_data.h"
#include "components/previews/core/previews_constants.h" #include "components/previews/core/previews_constants.h"
#include "components/previews/core/previews_switches.h" #include "components/previews/core/previews_switches.h"
...@@ -81,7 +82,8 @@ ParseHintsProtoFromCommandLine() { ...@@ -81,7 +82,8 @@ ParseHintsProtoFromCommandLine() {
PreviewsOptimizationGuide::PreviewsOptimizationGuide( PreviewsOptimizationGuide::PreviewsOptimizationGuide(
optimization_guide::OptimizationGuideService* optimization_guide_service, optimization_guide::OptimizationGuideService* optimization_guide_service,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
const base::FilePath& profile_path) const base::FilePath& profile_path,
PreviewsTopHostProvider* previews_top_host_provider)
: optimization_guide_service_(optimization_guide_service), : optimization_guide_service_(optimization_guide_service),
ui_task_runner_(ui_task_runner), ui_task_runner_(ui_task_runner),
background_task_runner_(base::CreateSequencedTaskRunnerWithTraits( background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
...@@ -89,6 +91,7 @@ PreviewsOptimizationGuide::PreviewsOptimizationGuide( ...@@ -89,6 +91,7 @@ PreviewsOptimizationGuide::PreviewsOptimizationGuide(
hint_cache_(std::make_unique<HintCache>( hint_cache_(std::make_unique<HintCache>(
std::make_unique<HintCacheLevelDBStore>(profile_path, std::make_unique<HintCacheLevelDBStore>(profile_path,
background_task_runner_))), background_task_runner_))),
previews_top_host_provider_(previews_top_host_provider),
ui_weak_ptr_factory_(this) { ui_weak_ptr_factory_(this) {
DCHECK(optimization_guide_service_); DCHECK(optimization_guide_service_);
hint_cache_->Initialize( hint_cache_->Initialize(
...@@ -216,6 +219,20 @@ void PreviewsOptimizationGuide::OnHintCacheInitialized() { ...@@ -216,6 +219,20 @@ void PreviewsOptimizationGuide::OnHintCacheInitialized() {
hint_cache_->MaybeCreateComponentUpdateData( hint_cache_->MaybeCreateComponentUpdateData(
base::Version(kManualConfigComponentVersion)))); base::Version(kManualConfigComponentVersion))));
} }
// If user is eligible for platform hints, currently controlled by a feature
// flag |kPreviewsOnePlatformHints|, start the OnePlatform client request.
// TODO(mcrouse): Add a check for user specific state in addition to the
// feature state:
// (1) Data saver should be enabled
// (2) Infobar notification does not need to be shown to the user.
if (previews::params::IsOnePlatformHintsEnabled()) {
// TODO(mcrouse): We will likely need to an async call and likely
// within a timer that will call GetOnePlatformClientHints().
// This is a temporary call for testing.
GetOnePlatformClientHints();
}
// Register as an observer regardless of hint proto override usage. This is // Register as an observer regardless of hint proto override usage. This is
// needed as a signal during testing. // needed as a signal during testing.
optimization_guide_service_->AddObserver(this); optimization_guide_service_->AddObserver(this);
...@@ -248,6 +265,22 @@ void PreviewsOptimizationGuide::OnHintsComponentAvailable( ...@@ -248,6 +265,22 @@ void PreviewsOptimizationGuide::OnHintsComponentAvailable(
std::move(next_update_closure_))); std::move(next_update_closure_)));
} }
void PreviewsOptimizationGuide::GetOnePlatformClientHints() {
std::vector<std::string> top_hosts = previews_top_host_provider_->GetTopHosts(
previews::params::MaxOnePlatformUpdateHosts());
DCHECK_GE(previews::params::MaxOnePlatformUpdateHosts(), top_hosts.size());
LOCAL_HISTOGRAM_COUNTS_100("Previews.HintsFetcher.GetHintsRequest.HostCount",
top_hosts.size());
// TODO(mcrouse) to build SimpleURLLoader to perform request from service
// for per-user client hints.
// Pass callback for when URLLoader request is successful to call
// PreviewOptimizationGuide::OnOnePlatformClientHintsReceived().
OnOnePlatformHintsReceived();
}
void PreviewsOptimizationGuide::UpdateHints( void PreviewsOptimizationGuide::UpdateHints(
base::OnceClosure update_closure, base::OnceClosure update_closure,
std::unique_ptr<PreviewsHints> hints) { std::unique_ptr<PreviewsHints> hints) {
...@@ -284,4 +317,9 @@ void PreviewsOptimizationGuide::ListenForNextUpdateForTesting( ...@@ -284,4 +317,9 @@ void PreviewsOptimizationGuide::ListenForNextUpdateForTesting(
next_update_closure_ = std::move(next_update_closure); next_update_closure_ = std::move(next_update_closure);
} }
void PreviewsOptimizationGuide::OnOnePlatformHintsReceived() {
// TODO(mcrouse): Once hints reseponse received from server, will need to
// update the cache and store.
}
} // namespace previews } // namespace previews
...@@ -34,6 +34,7 @@ class Hint; ...@@ -34,6 +34,7 @@ class Hint;
namespace previews { namespace previews {
class PreviewsHints; class PreviewsHints;
class PreviewsTopHostProvider;
class PreviewsUserData; class PreviewsUserData;
// A Previews optimization guide that makes decisions guided by hints received // A Previews optimization guide that makes decisions guided by hints received
...@@ -42,10 +43,12 @@ class PreviewsOptimizationGuide ...@@ -42,10 +43,12 @@ class PreviewsOptimizationGuide
: public optimization_guide::OptimizationGuideServiceObserver { : public optimization_guide::OptimizationGuideServiceObserver {
public: public:
// The embedder guarantees |optimization_guide_service| outlives |this|. // The embedder guarantees |optimization_guide_service| outlives |this|.
// The embedder guarantees that |previews_top_host_provider_| outlives |this|.
PreviewsOptimizationGuide( PreviewsOptimizationGuide(
optimization_guide::OptimizationGuideService* optimization_guide_service, optimization_guide::OptimizationGuideService* optimization_guide_service,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
const base::FilePath& profile_path); const base::FilePath& profile_path,
PreviewsTopHostProvider* previews_top_host_provider);
~PreviewsOptimizationGuide() override; ~PreviewsOptimizationGuide() override;
...@@ -116,6 +119,16 @@ class PreviewsOptimizationGuide ...@@ -116,6 +119,16 @@ class PreviewsOptimizationGuide
const GURL& document_url, const GURL& document_url,
const optimization_guide::proto::Hint* loaded_hint) const; const optimization_guide::proto::Hint* loaded_hint) const;
// Method to request OnePlatform client hints for user's sites with
// top engagement scores and creates a remote request to the OnePlatform
// Service. On request success OnOnePlatformHintsReceived callback will be
// called.
void GetOnePlatformClientHints();
// Called when the response form the OnePlatform Service for hints is
// received.
void OnOnePlatformHintsReceived();
// The OptimizationGuideService that this guide is listening to. Not owned. // The OptimizationGuideService that this guide is listening to. Not owned.
optimization_guide::OptimizationGuideService* optimization_guide_service_; optimization_guide::OptimizationGuideService* optimization_guide_service_;
...@@ -137,6 +150,9 @@ class PreviewsOptimizationGuide ...@@ -137,6 +150,9 @@ class PreviewsOptimizationGuide
// Used in testing to subscribe to an update event in this class. // Used in testing to subscribe to an update event in this class.
base::OnceClosure next_update_closure_; base::OnceClosure next_update_closure_;
// TopHostProvider that this guide can query. Not owned.
PreviewsTopHostProvider* previews_top_host_provider_;
// Used to get |weak_ptr_| to self on the UI thread. // Used to get |weak_ptr_| to self on the UI thread.
base::WeakPtrFactory<PreviewsOptimizationGuide> ui_weak_ptr_factory_; base::WeakPtrFactory<PreviewsOptimizationGuide> ui_weak_ptr_factory_;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "components/optimization_guide/hints_component_info.h" #include "components/optimization_guide/hints_component_info.h"
#include "components/optimization_guide/optimization_guide_service.h" #include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto/hints.pb.h"
#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_user_data.h" #include "components/previews/content/previews_user_data.h"
#include "components/previews/core/bloom_filter.h" #include "components/previews/core/bloom_filter.h"
#include "components/previews/core/previews_experiments.h" #include "components/previews/core/previews_experiments.h"
...@@ -66,6 +67,17 @@ class TestOptimizationGuideService ...@@ -66,6 +67,17 @@ class TestOptimizationGuideService
bool remove_observer_called_; bool remove_observer_called_;
}; };
// A test class implementation for unit testing previews_optimization_guide.
class TestPreviewsTopHostProvider : public PreviewsTopHostProvider {
public:
TestPreviewsTopHostProvider() {}
~TestPreviewsTopHostProvider() override {}
std::vector<std::string> GetTopHosts(size_t max_sites) const override {
return std::vector<std::string>();
}
};
class PreviewsOptimizationGuideTest : public testing::Test { class PreviewsOptimizationGuideTest : public testing::Test {
public: public:
PreviewsOptimizationGuideTest() {} PreviewsOptimizationGuideTest() {}
...@@ -105,7 +117,9 @@ class PreviewsOptimizationGuideTest : public testing::Test { ...@@ -105,7 +117,9 @@ class PreviewsOptimizationGuideTest : public testing::Test {
scoped_task_environment_.GetMainThreadTaskRunner()); scoped_task_environment_.GetMainThreadTaskRunner());
guide_ = std::make_unique<PreviewsOptimizationGuide>( guide_ = std::make_unique<PreviewsOptimizationGuide>(
optimization_guide_service_.get(), optimization_guide_service_.get(),
scoped_task_environment_.GetMainThreadTaskRunner(), temp_dir()); scoped_task_environment_.GetMainThreadTaskRunner(), temp_dir(),
previews_top_host_provider_.get());
// Add observer is called after the HintCache is fully initialized, // Add observer is called after the HintCache is fully initialized,
// indicating that the PreviewsOptimizationGuide is ready to process hints. // indicating that the PreviewsOptimizationGuide is ready to process hints.
while (!optimization_guide_service_->AddObserverCalled()) { while (!optimization_guide_service_->AddObserverCalled()) {
...@@ -177,6 +191,7 @@ class PreviewsOptimizationGuideTest : public testing::Test { ...@@ -177,6 +191,7 @@ class PreviewsOptimizationGuideTest : public testing::Test {
std::unique_ptr<PreviewsOptimizationGuide> guide_; std::unique_ptr<PreviewsOptimizationGuide> guide_;
std::unique_ptr<TestOptimizationGuideService> optimization_guide_service_; std::unique_ptr<TestOptimizationGuideService> optimization_guide_service_;
std::unique_ptr<TestPreviewsTopHostProvider> previews_top_host_provider_;
// Flag set when the OnLoadOptimizationHints callback runs. This indicates // Flag set when the OnLoadOptimizationHints callback runs. This indicates
// that MaybeLoadOptimizationHints() has completed its processing. // that MaybeLoadOptimizationHints() has completed its processing.
......
// 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_PREVIEWS_CONTENT_PREVIEWS_TOP_HOST_PROVIDER_H_
#define COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_TOP_HOST_PROVIDER_H_
#include <string>
#include <vector>
namespace previews {
// A class to handle querying for the top hosts for a user.
class PreviewsTopHostProvider {
public:
// 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) const = 0;
protected:
PreviewsTopHostProvider() {}
virtual ~PreviewsTopHostProvider() {}
};
} // namespace previews
#endif // COMPONENTS_PREVIEWS_CONTENT_PREVIEWS_TOP_HOST_PROVIDER_H_
...@@ -111,6 +111,11 @@ size_t MaxInMemoryHostsInBlackList() { ...@@ -111,6 +111,11 @@ size_t MaxInMemoryHostsInBlackList() {
"max_hosts_in_blacklist", 100); "max_hosts_in_blacklist", 100);
} }
size_t MaxOnePlatformUpdateHosts() {
return GetFieldTrialParamByFeatureAsInt(features::kPreviewsOnePlatformHints,
"max_oneplatform_update_hosts", 30);
}
int PerHostBlackListOptOutThreshold() { int PerHostBlackListOptOutThreshold() {
return GetParamValueAsInt(kClientSidePreviewsFieldTrial, return GetParamValueAsInt(kClientSidePreviewsFieldTrial,
"per_host_opt_out_threshold", 2); "per_host_opt_out_threshold", 2);
...@@ -327,6 +332,10 @@ bool IsOptimizationHintsEnabled() { ...@@ -327,6 +332,10 @@ bool IsOptimizationHintsEnabled() {
return base::FeatureList::IsEnabled(features::kOptimizationHints); return base::FeatureList::IsEnabled(features::kOptimizationHints);
} }
bool IsOnePlatformHintsEnabled() {
return base::FeatureList::IsEnabled(features::kPreviewsOnePlatformHints);
}
int NoScriptPreviewsInflationPercent() { int NoScriptPreviewsInflationPercent() {
// The default value was determined from lab experiment data of whitelisted // The default value was determined from lab experiment data of whitelisted
// URLs. It may be improved once there is enough UKM live experiment data // URLs. It may be improved once there is enough UKM live experiment data
......
...@@ -68,6 +68,10 @@ size_t MaxStoredHistoryLengthForHostIndifferentBlackList(); ...@@ -68,6 +68,10 @@ size_t MaxStoredHistoryLengthForHostIndifferentBlackList();
// The maximum number of hosts allowed in the in memory black list. // The maximum number of hosts allowed in the in memory black list.
size_t MaxInMemoryHostsInBlackList(); size_t MaxInMemoryHostsInBlackList();
// The maximum number of hosts requested by the client to the OnePlatform
// Service.
size_t MaxOnePlatformUpdateHosts();
// The number of recent navigations that were opted out of for a given host that // The number of recent navigations that were opted out of for a given host that
// would trigger that host to be blacklisted. // would trigger that host to be blacklisted.
int PerHostBlackListOptOutThreshold(); int PerHostBlackListOptOutThreshold();
...@@ -167,6 +171,10 @@ size_t GetMaxPageHintsInMemoryThreshhold(); ...@@ -167,6 +171,10 @@ size_t GetMaxPageHintsInMemoryThreshhold();
// Whether server optimization hints are enabled. // Whether server optimization hints are enabled.
bool IsOptimizationHintsEnabled(); bool IsOptimizationHintsEnabled();
// Returns true if the feature to fetch user-specific hints using
// the OnePlatform API is enabled.
bool IsOnePlatformHintsEnabled();
// For estimating NoScript data savings, this is the percentage factor to // For estimating NoScript data savings, this is the percentage factor to
// multiple by the network bytes for inflating the original_bytes count. // multiple by the network bytes for inflating the original_bytes count.
int NoScriptPreviewsInflationPercent(); int NoScriptPreviewsInflationPercent();
......
...@@ -110,5 +110,9 @@ const base::Feature kDataSaverLiteModeRebranding{ ...@@ -110,5 +110,9 @@ const base::Feature kDataSaverLiteModeRebranding{
const base::Feature kPreviewsReloadsAreSoftOptOuts{ const base::Feature kPreviewsReloadsAreSoftOptOuts{
"PreviewsReloadsAreSoftOptOuts", base::FEATURE_DISABLED_BY_DEFAULT}; "PreviewsReloadsAreSoftOptOuts", base::FEATURE_DISABLED_BY_DEFAULT};
// Enables using the OnePlatform Client Hints requests.
const base::Feature kPreviewsOnePlatformHints{
"PreviewsOnePlatformHints", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace features } // namespace features
} // namespace previews } // namespace previews
...@@ -25,6 +25,7 @@ extern const base::Feature kSlowPageTriggering; ...@@ -25,6 +25,7 @@ extern const base::Feature kSlowPageTriggering;
extern const base::Feature kHTTPSServerPreviewsUsingURLLoader; extern const base::Feature kHTTPSServerPreviewsUsingURLLoader;
extern const base::Feature kDataSaverLiteModeRebranding; extern const base::Feature kDataSaverLiteModeRebranding;
extern const base::Feature kPreviewsReloadsAreSoftOptOuts; extern const base::Feature kPreviewsReloadsAreSoftOptOuts;
extern const base::Feature kPreviewsOnePlatformHints;
} // namespace features } // namespace features
} // namespace previews } // namespace previews
......
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