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

Add a WebContentsObserver that triggers loading of hints on navigation

Bug: 969558
Change-Id: Iebcfcf47a59694b0cac12fb85d06daa7a8735e9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1726236Reviewed-by: default avatarDoug Arnett <dougarnett@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Sophie Chang <sophiechang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#683780}
parent 2f63ef69
...@@ -929,6 +929,8 @@ jumbo_split_static_library("browser") { ...@@ -929,6 +929,8 @@ jumbo_split_static_library("browser") {
"optimization_guide/optimization_guide_keyed_service.h", "optimization_guide/optimization_guide_keyed_service.h",
"optimization_guide/optimization_guide_keyed_service_factory.cc", "optimization_guide/optimization_guide_keyed_service_factory.cc",
"optimization_guide/optimization_guide_keyed_service_factory.h", "optimization_guide/optimization_guide_keyed_service_factory.h",
"optimization_guide/optimization_guide_web_contents_observer.cc",
"optimization_guide/optimization_guide_web_contents_observer.h",
"page_load_metrics/metrics_navigation_throttle.cc", "page_load_metrics/metrics_navigation_throttle.cc",
"page_load_metrics/metrics_navigation_throttle.h", "page_load_metrics/metrics_navigation_throttle.h",
"page_load_metrics/metrics_web_contents_observer.cc", "page_load_metrics/metrics_web_contents_observer.cc",
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto/hints.pb.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
namespace { namespace {
...@@ -216,15 +217,14 @@ void OptimizationGuideHintsManager::UpdateComponentHints( ...@@ -216,15 +217,14 @@ void OptimizationGuideHintsManager::UpdateComponentHints(
void OptimizationGuideHintsManager::OnComponentHintsUpdated( void OptimizationGuideHintsManager::OnComponentHintsUpdated(
base::OnceClosure update_closure, base::OnceClosure update_closure,
bool hints_updated) { bool hints_updated) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Record the result of updating the hints. This is used as a signal for the // Record the result of updating the hints. This is used as a signal for the
// hints being fully processed in testing. // hints being fully processed in testing.
// TODO(sophiechang): Change this back to just a Result suffix once we LOCAL_HISTOGRAM_BOOLEAN(
// have the flag to not record the histogram in Previews. optimization_guide::kComponentHintsUpdatedResultHistogramString,
LOCAL_HISTOGRAM_BOOLEAN("OptimizationGuide.UpdateComponentHints.Result2", hints_updated);
hints_updated);
MaybeRunUpdateClosure(std::move(update_closure)); MaybeRunUpdateClosure(std::move(update_closure));
} }
...@@ -235,3 +235,33 @@ void OptimizationGuideHintsManager::ListenForNextUpdateForTesting( ...@@ -235,3 +235,33 @@ void OptimizationGuideHintsManager::ListenForNextUpdateForTesting(
<< "Only one update closure is supported at a time"; << "Only one update closure is supported at a time";
next_update_closure_ = std::move(next_update_closure); next_update_closure_ = std::move(next_update_closure);
} }
void OptimizationGuideHintsManager::LoadHintForNavigation(
content::NavigationHandle* navigation_handle,
base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
const auto& url = navigation_handle->GetURL();
if (!url.has_host()) {
std::move(callback).Run();
return;
}
hint_cache_->LoadHint(
url.host(),
base::BindOnce(&OptimizationGuideHintsManager::OnHintLoaded,
ui_weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void OptimizationGuideHintsManager::OnHintLoaded(
base::OnceClosure callback,
const optimization_guide::proto::Hint* loaded_hint) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Record the result of loading a hint. This is used as a signal for testing.
LOCAL_HISTOGRAM_BOOLEAN("OptimizationGuide.LoadedHint.Result", loaded_hint);
// Run the callback now that the hint is loaded. This is used as a signal by
// tests.
std::move(callback).Run();
}
...@@ -16,11 +16,18 @@ namespace base { ...@@ -16,11 +16,18 @@ namespace base {
class FilePath; class FilePath;
} // namespace base } // namespace base
namespace content {
class NavigationHandle;
} // namespace content
namespace leveldb_proto { namespace leveldb_proto {
class ProtoDatabaseProvider; class ProtoDatabaseProvider;
} // namespace leveldb_proto } // namespace leveldb_proto
namespace optimization_guide { namespace optimization_guide {
namespace proto {
class Hint;
} // namespace proto
class HintCache; class HintCache;
class HintUpdateData; class HintUpdateData;
struct HintsComponentInfo; struct HintsComponentInfo;
...@@ -51,6 +58,13 @@ class OptimizationGuideHintsManager ...@@ -51,6 +58,13 @@ class OptimizationGuideHintsManager
// is called and the corresponding hints have been updated. // is called and the corresponding hints have been updated.
void ListenForNextUpdateForTesting(base::OnceClosure next_update_closure); void ListenForNextUpdateForTesting(base::OnceClosure next_update_closure);
// Loads the hint if available.
// |callback| is run when the request has finished regardless of whether there
// was actually a hint for that load or not. The callback can be used as a
// signal for tests.
void LoadHintForNavigation(content::NavigationHandle* navigation_handle,
base::OnceClosure callback);
private: private:
// Callback run after the hint cache is fully initialized. At this point, the // Callback run after the hint cache is fully initialized. At this point, the
// OptimizationGuideHintsManager is ready to process hints. // OptimizationGuideHintsManager is ready to process hints.
...@@ -64,7 +78,11 @@ class OptimizationGuideHintsManager ...@@ -64,7 +78,11 @@ class OptimizationGuideHintsManager
// Called when the hints have been fully updated with the latest hints from // Called when the hints have been fully updated with the latest hints from
// the Component Updater. This is used as a signal during tests. // the Component Updater. This is used as a signal during tests.
void OnComponentHintsUpdated(base::OnceClosure update_closure, void OnComponentHintsUpdated(base::OnceClosure update_closure,
bool hints_updated); bool hints_updated) const;
// Called when the request to load a hint has completed.
void OnHintLoaded(base::OnceClosure callback,
const optimization_guide::proto::Hint* loaded_hint) const;
// The OptimizationGuideService that this guide is listening to. Not owned. // The OptimizationGuideService that this guide is listening to. Not owned.
optimization_guide::OptimizationGuideService* const optimization_guide::OptimizationGuideService* const
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto/hints.pb.h"
#include "components/optimization_guide/proto_database_provider_test_base.h" #include "components/optimization_guide/proto_database_provider_test_base.h"
#include "components/prefs/testing_pref_service.h" #include "components/prefs/testing_pref_service.h"
#include "content/public/test/mock_navigation_handle.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
class TestOptimizationGuideService class TestOptimizationGuideService
...@@ -134,9 +135,17 @@ class OptimizationGuideHintsManagerTest ...@@ -134,9 +135,17 @@ class OptimizationGuideHintsManagerTest
ProcessHints(config, version); ProcessHints(config, version);
} }
OptimizationGuideHintsManager* hints_manager() const {
return hints_manager_.get();
}
GURL url_with_hints() const {
return GURL("https://somedomain.org/news/whatever");
}
base::FilePath temp_dir() const { return temp_dir_.GetPath(); } base::FilePath temp_dir() const { return temp_dir_.GetPath(); }
TestingPrefServiceSimple* pref_service() { return pref_service_.get(); } TestingPrefServiceSimple* pref_service() const { return pref_service_.get(); }
protected: protected:
void RunUntilIdle() { void RunUntilIdle() {
...@@ -191,7 +200,7 @@ TEST_F(OptimizationGuideHintsManagerTest, ...@@ -191,7 +200,7 @@ TEST_F(OptimizationGuideHintsManagerTest,
// However, we still expect the local histogram for the hints being updated to // However, we still expect the local histogram for the hints being updated to
// be recorded. // be recorded.
histogram_tester.ExpectUniqueSample( histogram_tester.ExpectUniqueSample(
"OptimizationGuide.UpdateComponentHints.Result2", true, 1); "OptimizationGuide.UpdateComponentHints.Result", true, 1);
} }
TEST_F(OptimizationGuideHintsManagerTest, TEST_F(OptimizationGuideHintsManagerTest,
...@@ -207,7 +216,7 @@ TEST_F(OptimizationGuideHintsManagerTest, ...@@ -207,7 +216,7 @@ TEST_F(OptimizationGuideHintsManagerTest,
histogram_tester.ExpectTotalCount("OptimizationGuide.ProcessHintsResult", 0); histogram_tester.ExpectTotalCount("OptimizationGuide.ProcessHintsResult", 0);
// We also do not expect to update the component hints with bad hints either. // We also do not expect to update the component hints with bad hints either.
histogram_tester.ExpectTotalCount( histogram_tester.ExpectTotalCount(
"OptimizationGuide.UpdateComponentHints.Result2", 0); "OptimizationGuide.UpdateComponentHints.Result", 0);
} }
TEST_F(OptimizationGuideHintsManagerTest, TEST_F(OptimizationGuideHintsManagerTest,
...@@ -238,7 +247,7 @@ TEST_F(OptimizationGuideHintsManagerTest, ...@@ -238,7 +247,7 @@ TEST_F(OptimizationGuideHintsManagerTest,
// However, we still expect the local histogram for the hints being updated // However, we still expect the local histogram for the hints being updated
// to be recorded. // to be recorded.
histogram_tester.ExpectUniqueSample( histogram_tester.ExpectUniqueSample(
"OptimizationGuide.UpdateComponentHints.Result2", true, 1); "OptimizationGuide.UpdateComponentHints.Result", true, 1);
} }
// Test that a new component coming in does not update the component hints. // Test that a new component coming in does not update the component hints.
...@@ -250,7 +259,7 @@ TEST_F(OptimizationGuideHintsManagerTest, ...@@ -250,7 +259,7 @@ TEST_F(OptimizationGuideHintsManagerTest,
histogram_tester.ExpectTotalCount("OptimizationGuide.ProcessHintsResult", histogram_tester.ExpectTotalCount("OptimizationGuide.ProcessHintsResult",
0); 0);
histogram_tester.ExpectTotalCount( histogram_tester.ExpectTotalCount(
"OptimizationGuide.UpdateComponentHints.Result2", 0); "OptimizationGuide.UpdateComponentHints.Result", 0);
} }
} }
...@@ -421,3 +430,50 @@ TEST_F(OptimizationGuideHintsManagerTest, ProcessHintsWithInvalidPref) { ...@@ -421,3 +430,50 @@ TEST_F(OptimizationGuideHintsManagerTest, ProcessHintsWithInvalidPref) {
optimization_guide::ProcessHintsComponentResult::kSuccess, 1); optimization_guide::ProcessHintsComponentResult::kSuccess, 1);
} }
} }
TEST_F(OptimizationGuideHintsManagerTest, LoadHintForNavigationWithHint) {
base::HistogramTester histogram_tester;
InitializeWithDefaultConfig("3.0.0.0");
content::MockNavigationHandle navigation_handle;
navigation_handle.set_url(url_with_hints());
base::RunLoop run_loop;
hints_manager()->LoadHintForNavigation(&navigation_handle,
run_loop.QuitClosure());
run_loop.Run();
histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result",
true, 1);
}
TEST_F(OptimizationGuideHintsManagerTest, LoadHintForNavigationNoHint) {
base::HistogramTester histogram_tester;
InitializeWithDefaultConfig("3.0.0.0");
content::MockNavigationHandle navigation_handle;
navigation_handle.set_url(GURL("https://notinhints.com"));
base::RunLoop run_loop;
hints_manager()->LoadHintForNavigation(&navigation_handle,
run_loop.QuitClosure());
run_loop.Run();
histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result",
false, 1);
}
TEST_F(OptimizationGuideHintsManagerTest, LoadHintForNavigationNoHost) {
base::HistogramTester histogram_tester;
InitializeWithDefaultConfig("3.0.0.0");
content::MockNavigationHandle navigation_handle;
navigation_handle.set_url(GURL("blargh"));
base::RunLoop run_loop;
hints_manager()->LoadHintForNavigation(&navigation_handle,
run_loop.QuitClosure());
run_loop.Run();
histogram_tester.ExpectTotalCount("OptimizationGuide.LoadedHint.Result", 0);
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h" #include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
#include "components/optimization_guide/optimization_guide_service.h" #include "components/optimization_guide/optimization_guide_service.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
OptimizationGuideKeyedService::OptimizationGuideKeyedService( OptimizationGuideKeyedService::OptimizationGuideKeyedService(
content::BrowserContext* browser_context) content::BrowserContext* browser_context)
...@@ -36,6 +38,22 @@ void OptimizationGuideKeyedService::Initialize( ...@@ -36,6 +38,22 @@ void OptimizationGuideKeyedService::Initialize(
database_provider); database_provider);
} }
void OptimizationGuideKeyedService::RegisterOptimizationTypes(
std::vector<optimization_guide::proto::OptimizationType>
optimization_types) {
for (const auto optimization_type : optimization_types) {
registered_optimization_types_.insert(optimization_type);
}
}
void OptimizationGuideKeyedService::MaybeLoadHintForNavigation(
content::NavigationHandle* navigation_handle) {
if (!hints_manager_ || registered_optimization_types_.empty())
return;
hints_manager_->LoadHintForNavigation(navigation_handle, base::DoNothing());
}
void OptimizationGuideKeyedService::Shutdown() { void OptimizationGuideKeyedService::Shutdown() {
if (hints_manager_) { if (hints_manager_) {
hints_manager_->Shutdown(); hints_manager_->Shutdown();
......
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
#define CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_KEYED_SERVICE_H_ #define CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_KEYED_SERVICE_H_
#include <memory> #include <memory>
#include <unordered_set>
#include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "components/optimization_guide/proto/hints.pb.h"
namespace base { namespace base {
class FilePath; class FilePath;
...@@ -16,6 +19,7 @@ class FilePath; ...@@ -16,6 +19,7 @@ class FilePath;
namespace content { namespace content {
class BrowserContext; class BrowserContext;
class NavigationHandle;
} // namespace content } // namespace content
namespace leveldb_proto { namespace leveldb_proto {
...@@ -46,12 +50,25 @@ class OptimizationGuideKeyedService : public KeyedService { ...@@ -46,12 +50,25 @@ class OptimizationGuideKeyedService : public KeyedService {
return hints_manager_.get(); return hints_manager_.get();
} }
// Registers the optimization types that intend to be queried during the
// session.
void RegisterOptimizationTypes(
std::vector<optimization_guide::proto::OptimizationType>
optimization_types);
// Prompts the load of the hint for the navigation, if there is at least one
// optimization type registered and there is a hint available.
void MaybeLoadHintForNavigation(content::NavigationHandle* navigation_handle);
// KeyedService implementation. // KeyedService implementation.
void Shutdown() override; void Shutdown() override;
private: private:
std::unique_ptr<OptimizationGuideHintsManager> hints_manager_; std::unique_ptr<OptimizationGuideHintsManager> hints_manager_;
std::unordered_set<optimization_guide::proto::OptimizationType>
registered_optimization_types_;
content::BrowserContext* browser_context_; content::BrowserContext* browser_context_;
DISALLOW_COPY_AND_ASSIGN(OptimizationGuideKeyedService); DISALLOW_COPY_AND_ASSIGN(OptimizationGuideKeyedService);
......
...@@ -12,10 +12,13 @@ ...@@ -12,10 +12,13 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/optimization_guide/optimization_guide_features.h" #include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto/hints.pb.h"
#include "components/optimization_guide/test_hints_component_creator.h" #include "components/optimization_guide/test_hints_component_creator.h"
#include "content/public/test/browser_test_utils.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"
namespace { namespace {
...@@ -34,6 +37,22 @@ int GetTotalHistogramSamples(const base::HistogramTester& histogram_tester, ...@@ -34,6 +37,22 @@ int GetTotalHistogramSamples(const base::HistogramTester& histogram_tester,
return total; 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::ThreadPoolInstance::Get()->FlushForTesting();
base::RunLoop().RunUntilIdle();
total = GetTotalHistogramSamples(histogram_tester, histogram_name);
if (total >= count)
return total;
}
}
} // namespace } // namespace
using OptimizationGuideKeyedServiceDisabledBrowserTest = InProcessBrowserTest; using OptimizationGuideKeyedServiceDisabledBrowserTest = InProcessBrowserTest;
...@@ -74,6 +93,27 @@ class OptimizationGuideKeyedServiceBrowserTest ...@@ -74,6 +93,27 @@ class OptimizationGuideKeyedServiceBrowserTest
OptimizationGuideKeyedServiceDisabledBrowserTest::SetUp(); OptimizationGuideKeyedServiceDisabledBrowserTest::SetUp();
} }
void SetUpOnMainThread() override {
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&OptimizationGuideKeyedServiceBrowserTest::HandleRequest,
base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
url_with_hints_ =
embedded_test_server()->GetURL("somehost.com", "/hashints/whatever");
PushHintsComponentAndWaitForCompletion();
OptimizationGuideKeyedServiceDisabledBrowserTest::SetUpOnMainThread();
}
void RegisterWithKeyedService() {
OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});
}
GURL url_with_hints() { return url_with_hints_; }
private:
void PushHintsComponentAndWaitForCompletion() { void PushHintsComponentAndWaitForCompletion() {
base::RunLoop run_loop; base::RunLoop run_loop;
OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile()) OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
...@@ -82,7 +122,8 @@ class OptimizationGuideKeyedServiceBrowserTest ...@@ -82,7 +122,8 @@ class OptimizationGuideKeyedServiceBrowserTest
const optimization_guide::HintsComponentInfo& component_info = const optimization_guide::HintsComponentInfo& component_info =
test_hints_component_creator_.CreateHintsComponentInfoWithPageHints( test_hints_component_creator_.CreateHintsComponentInfoWithPageHints(
optimization_guide::proto::NOSCRIPT, {"somehost.com"}, "*", {}); optimization_guide::proto::NOSCRIPT, {url_with_hints_.host()}, "*",
{});
g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent( g_browser_process->optimization_guide_service()->MaybeUpdateHintsComponent(
component_info); component_info);
...@@ -90,7 +131,18 @@ class OptimizationGuideKeyedServiceBrowserTest ...@@ -90,7 +131,18 @@ class OptimizationGuideKeyedServiceBrowserTest
run_loop.Run(); run_loop.Run();
} }
private: std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
const net::test_server::HttpRequest& request) {
std::unique_ptr<net::test_server::BasicHttpResponse> response;
if (request.GetURL().spec().find("redirect") != std::string::npos) {
response.reset(new net::test_server::BasicHttpResponse);
response->set_code(net::HTTP_FOUND);
response->AddCustomHeader("Location", url_with_hints().spec());
}
return std::move(response);
}
GURL url_with_hints_;
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
optimization_guide::testing::TestHintsComponentCreator optimization_guide::testing::TestHintsComponentCreator
test_hints_component_creator_; test_hints_component_creator_;
...@@ -98,16 +150,67 @@ class OptimizationGuideKeyedServiceBrowserTest ...@@ -98,16 +150,67 @@ class OptimizationGuideKeyedServiceBrowserTest
DISALLOW_COPY_AND_ASSIGN(OptimizationGuideKeyedServiceBrowserTest); DISALLOW_COPY_AND_ASSIGN(OptimizationGuideKeyedServiceBrowserTest);
}; };
IN_PROC_BROWSER_TEST_F(
OptimizationGuideKeyedServiceBrowserTest,
NavigateToPageWithHintsButNoRegistrationDoesNotAttemptToLoadHint) {
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), url_with_hints());
histogram_tester.ExpectTotalCount("OptimizationGuide.LoadedHint.Result", 0);
}
IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceBrowserTest, IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceBrowserTest,
VerifyHintsReceivedWhenPushed) { NavigateToPageWithHintsLoadsHint) {
RegisterWithKeyedService();
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), url_with_hints());
EXPECT_GT(RetryForHistogramUntilCountReached(
histogram_tester, "OptimizationGuide.LoadedHint.Result", 1),
0);
// There is a hint that matches this URL, so there should be an attempt to
// load a hint that succeeds.
histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result",
true, 1);
}
IN_PROC_BROWSER_TEST_F(
OptimizationGuideKeyedServiceBrowserTest,
NavigateToPageThatRedirectsToUrlWithHintsShouldAttemptTwoLoads) {
RegisterWithKeyedService();
base::HistogramTester histogram_tester;
GURL first_url = embedded_test_server()->GetURL("/redirect");
ui_test_utils::NavigateToURL(browser(), first_url);
EXPECT_GE(RetryForHistogramUntilCountReached(
histogram_tester, "OptimizationGuide.LoadedHint.Result", 2),
2);
// Should attempt and fail to load a hint for the initial navigation.
histogram_tester.ExpectBucketCount("OptimizationGuide.LoadedHint.Result",
false, 1);
// Should attempt and succeed to load a hint once for the redirect.
histogram_tester.ExpectBucketCount("OptimizationGuide.LoadedHint.Result",
true, 1);
}
IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceBrowserTest,
NavigateToPageWithoutHint) {
RegisterWithKeyedService();
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
PushHintsComponentAndWaitForCompletion(); ui_test_utils::NavigateToURL(browser(), GURL("https://nohints.com/"));
// TODO(crbug/969558): Update browser test to better support multiple profile EXPECT_GE(RetryForHistogramUntilCountReached(
// cases. histogram_tester, "OptimizationGuide.LoadedHint.Result", 1),
EXPECT_GT( 1);
GetTotalHistogramSamples( // There were no hints that match this URL, but there should still be an
histogram_tester, "OptimizationGuide.UpdateComponentHints.Result2"), // attempt to load a hint but still fail.
0); histogram_tester.ExpectUniqueSample("OptimizationGuide.LoadedHint.Result",
false, 1);
} }
// 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/optimization_guide/optimization_guide_web_contents_observer.h"
#include "base/base64.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
OptimizationGuideWebContentsObserver::OptimizationGuideWebContentsObserver(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
optimization_guide_keyed_service_ =
OptimizationGuideKeyedServiceFactory::GetForProfile(
Profile::FromBrowserContext(web_contents->GetBrowserContext()));
}
OptimizationGuideWebContentsObserver::~OptimizationGuideWebContentsObserver() =
default;
void OptimizationGuideWebContentsObserver::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame())
return;
if (!optimization_guide_keyed_service_)
return;
optimization_guide_keyed_service_->MaybeLoadHintForNavigation(
navigation_handle);
}
void OptimizationGuideWebContentsObserver::DidRedirectNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame())
return;
if (!optimization_guide_keyed_service_)
return;
optimization_guide_keyed_service_->MaybeLoadHintForNavigation(
navigation_handle);
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(OptimizationGuideWebContentsObserver)
// 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_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_WEB_CONTENTS_OBSERVER_H_
#define CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_WEB_CONTENTS_OBSERVER_H_
#include <string>
#include <vector>
#include "base/macros.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
namespace content {
class NavigationHandle;
} // namespace content
class OptimizationGuideKeyedService;
// Observes navigation events.
class OptimizationGuideWebContentsObserver
: public content::WebContentsObserver,
public content::WebContentsUserData<
OptimizationGuideWebContentsObserver> {
public:
~OptimizationGuideWebContentsObserver() override;
private:
friend class content::WebContentsUserData<
OptimizationGuideWebContentsObserver>;
explicit OptimizationGuideWebContentsObserver(
content::WebContents* web_contents);
// Overridden from content::WebContentsObserver.
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override;
void DidRedirectNavigation(
content::NavigationHandle* navigation_handle) override;
// Initialized in constructor. It may be null if the
// OptimizationGuideKeyedService feature is not enabled.
OptimizationGuideKeyedService* optimization_guide_keyed_service_ = nullptr;
WEB_CONTENTS_USER_DATA_KEY_DECL();
DISALLOW_COPY_AND_ASSIGN(OptimizationGuideWebContentsObserver);
};
#endif // CHROME_BROWSER_OPTIMIZATION_GUIDE_OPTIMIZATION_GUIDE_WEB_CONTENTS_OBSERVER_H_
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "chrome/browser/metrics/renderer_uptime_web_contents_observer.h" #include "chrome/browser/metrics/renderer_uptime_web_contents_observer.h"
#include "chrome/browser/native_file_system/native_file_system_permission_request_manager.h" #include "chrome/browser/native_file_system/native_file_system_permission_request_manager.h"
#include "chrome/browser/net/net_error_tab_helper.h" #include "chrome/browser/net/net_error_tab_helper.h"
#include "chrome/browser/optimization_guide/optimization_guide_web_contents_observer.h"
#include "chrome/browser/page_load_metrics/page_load_metrics_initialize.h" #include "chrome/browser/page_load_metrics/page_load_metrics_initialize.h"
#include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h"
#include "chrome/browser/performance_manager/performance_manager.h" #include "chrome/browser/performance_manager/performance_manager.h"
...@@ -230,6 +231,7 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) { ...@@ -230,6 +231,7 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) {
NativeFileSystemPermissionRequestManager::CreateForWebContents(web_contents); NativeFileSystemPermissionRequestManager::CreateForWebContents(web_contents);
NavigationCorrectionTabObserver::CreateForWebContents(web_contents); NavigationCorrectionTabObserver::CreateForWebContents(web_contents);
NavigationMetricsRecorder::CreateForWebContents(web_contents); NavigationMetricsRecorder::CreateForWebContents(web_contents);
OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents);
OutOfMemoryReporter::CreateForWebContents(web_contents); OutOfMemoryReporter::CreateForWebContents(web_contents);
chrome::InitializePageLoadMetricsForWebContents(web_contents); chrome::InitializePageLoadMetricsForWebContents(web_contents);
PDFPluginPlaceholderObserver::CreateForWebContents(web_contents); PDFPluginPlaceholderObserver::CreateForWebContents(web_contents);
......
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