Commit 417f692e authored by Clark DuVall's avatar Clark DuVall Committed by Commit Bot

[WebLayer] Implement client hints in WebLayer

This implements basic client hints functionality. Still TODO after this
patch to make sure ContentSettingsAgentImpl is working as expected:
- Sync content settings to renderer
- Add ContentSettingsManager implementation for WebLayer

Bug: 1065537
Change-Id: I3a281c2a6a472ba9e1d79ff860d5bb94367cf888
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2145156
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759401}
parent 5c7136df
......@@ -110,6 +110,8 @@ source_set("weblayer_lib_base") {
"browser/browser_main_parts_impl.h",
"browser/browser_process.cc",
"browser/browser_process.h",
"browser/client_hints_factory.cc",
"browser/client_hints_factory.h",
"browser/content_browser_client_impl.cc",
"browser/content_browser_client_impl.h",
"browser/controls_visibility_reason.h",
......@@ -235,7 +237,9 @@ source_set("weblayer_lib_base") {
"//components/base32",
"//components/captive_portal/core:buildflags",
"//components/cdm/renderer",
"//components/client_hints/browser",
"//components/content_settings/core/browser",
"//components/content_settings/renderer",
"//components/crash/content/browser",
"//components/crash/core/app",
"//components/crash/core/common",
......@@ -273,6 +277,7 @@ source_set("weblayer_lib_base") {
"//content/public/browser",
"//content/public/child",
"//content/public/common",
"//content/public/common:client_hints_mojom",
"//content/public/common:service_names",
"//content/public/renderer",
"//content/public/utility",
......
......@@ -8,6 +8,7 @@ include_rules = [
"+components/browser_ui",
"+components/captive_portal",
"+components/cdm/browser",
"+components/client_hints/browser",
"+components/content_settings/core/common",
"+components/crash/content/browser",
"+components/crash/core/common",
......
......@@ -5,6 +5,7 @@
#include "weblayer/browser/browser_context_impl.h"
#include "base/threading/thread_restrictions.h"
#include "components/client_hints/browser/client_hints.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/download/public/common/in_progress_download_manager.h"
#include "components/embedder_support/pref_names.h"
......@@ -24,6 +25,7 @@
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
#include "weblayer/browser/client_hints_factory.h"
#include "weblayer/browser/permissions/permission_manager_factory.h"
#include "weblayer/browser/stateful_ssl_host_state_delegate_factory.h"
#include "weblayer/public/common/switches.h"
......@@ -157,8 +159,7 @@ BrowserContextImpl::GetPermissionControllerDelegate() {
content::ClientHintsControllerDelegate*
BrowserContextImpl::GetClientHintsControllerDelegate() {
// TODO(crbug.com/1065537): implement me.
return nullptr;
return ClientHintsFactory::GetForBrowserContext(this);
}
content::BackgroundFetchDelegate*
......
......@@ -145,6 +145,8 @@ void BrowserMainPartsImpl::PreMainMessageLoopRun() {
content::WebUIControllerFactory::RegisterFactory(
WebUIControllerFactory::GetInstance());
BrowserProcess::GetInstance()->PreMainMessageLoopRun();
if (main_function_params_.ui_task) {
std::move(*main_function_params_.ui_task).Run();
delete main_function_params_.ui_task;
......
......@@ -15,6 +15,9 @@
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/network_service_instance.h"
#include "services/network/public/cpp/network_quality_tracker.h"
#include "weblayer/browser/download_manager_delegate_impl.h"
#include "weblayer/browser/system_network_context_manager.h"
#include "weblayer/common/weblayer_paths.h"
......@@ -42,6 +45,10 @@ BrowserProcess* BrowserProcess::GetInstance() {
return g_browser_process;
}
void BrowserProcess::PreMainMessageLoopRun() {
CreateNetworkQualityObserver();
}
void BrowserProcess::StartTearDown() {
if (local_state_)
local_state_->CommitPendingWrite();
......@@ -93,9 +100,25 @@ network_time::NetworkTimeTracker* BrowserProcess::GetNetworkTimeTracker() {
return network_time_tracker_.get();
}
network::NetworkQualityTracker* BrowserProcess::GetNetworkQualityTracker() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!network_quality_tracker_) {
network_quality_tracker_ = std::make_unique<network::NetworkQualityTracker>(
base::BindRepeating(&content::GetNetworkService));
}
return network_quality_tracker_.get();
}
void BrowserProcess::RegisterPrefs(PrefRegistrySimple* pref_registry) {
network_time::NetworkTimeTracker::RegisterPrefs(pref_registry);
pref_registry->RegisterIntegerPref(kDownloadNextIDPref, 0);
}
void BrowserProcess::CreateNetworkQualityObserver() {
DCHECK(!network_quality_observer_);
network_quality_observer_ =
content::CreateNetworkQualityObserver(GetNetworkQualityTracker());
DCHECK(network_quality_observer_);
}
} // namespace weblayer
......@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "services/network/public/cpp/network_quality_tracker.h"
class PrefRegistrySimple;
class PrefService;
......@@ -33,18 +34,33 @@ class BrowserProcess {
static BrowserProcess* GetInstance();
// Called after the threads have been created but before the message loops
// starts running. Allows the browser process to do any initialization that
// requires all threads running.
void PreMainMessageLoopRun();
// Does cleanup that needs to occur before threads are torn down.
void StartTearDown();
PrefService* GetLocalState();
scoped_refptr<network::SharedURLLoaderFactory> GetSharedURLLoaderFactory();
network_time::NetworkTimeTracker* GetNetworkTimeTracker();
network::NetworkQualityTracker* GetNetworkQualityTracker();
private:
void RegisterPrefs(PrefRegistrySimple* pref_registry);
void CreateNetworkQualityObserver();
std::unique_ptr<PrefService> local_state_;
std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
std::unique_ptr<network::NetworkQualityTracker> network_quality_tracker_;
// Listens to NetworkQualityTracker and sends network quality updates to the
// renderer.
std::unique_ptr<
network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
network_quality_observer_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(BrowserProcess);
......
// Copyright 2020 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 "base/strings/string_number_conversions.h"
#include "content/public/test/browser_test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/tab_impl.h"
#include "weblayer/shell/browser/shell.h"
#include "weblayer/test/weblayer_browser_test.h"
#include "weblayer/test/weblayer_browser_test_utils.h"
namespace weblayer {
class ClientHintsBrowserTest : public WebLayerBrowserTest {
public:
void SetUpOnMainThread() override {
WebLayerBrowserTest::SetUpOnMainThread();
BrowserProcess::GetInstance()
->GetNetworkQualityTracker()
->ReportRTTsAndThroughputForTesting(
base::TimeDelta::FromMilliseconds(500), 100);
}
std::string GetBody() {
return ExecuteScript(shell(), "document.body.innerText", true).GetString();
}
};
IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, Navigation) {
EXPECT_TRUE(embedded_test_server()->Start());
NavigateAndWaitForCompletion(
embedded_test_server()->GetURL(
"/set-header?Accept-CH: device-memory,rtt&Accept-CH-Lifetime: 86400"),
shell());
NavigateAndWaitForCompletion(
embedded_test_server()->GetURL("/echoheader?device-memory"), shell());
double device_memory = 0.0;
ASSERT_TRUE(base::StringToDouble(GetBody(), &device_memory));
EXPECT_GT(device_memory, 0.0);
NavigateAndWaitForCompletion(
embedded_test_server()->GetURL("/echoheader?rtt"), shell());
int rtt = 0;
ASSERT_TRUE(base::StringToInt(GetBody(), &rtt));
EXPECT_GT(rtt, 0);
}
IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, Subresource) {
EXPECT_TRUE(embedded_test_server()->Start());
NavigateAndWaitForCompletion(
embedded_test_server()->GetURL(
"/set-header?Accept-CH: device-memory,rtt&Accept-CH-Lifetime: 86400"),
shell());
constexpr char kScript[] = R"(
new Promise(function (resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open("GET", "/echoheader?" + $1);
xhr.onload = () => {
resolve(xhr.response);
};
xhr.send();
})
)";
content::WebContents* web_contents =
static_cast<TabImpl*>(shell()->tab())->web_contents();
double device_memory = 0.0;
ASSERT_TRUE(base::StringToDouble(
content::EvalJs(web_contents,
content::JsReplace(kScript, "device-memory"))
.ExtractString(),
&device_memory));
EXPECT_GT(device_memory, 0.0);
int rtt = 0;
ASSERT_TRUE(base::StringToInt(
content::EvalJs(web_contents, content::JsReplace(kScript, "rtt"))
.ExtractString(),
&rtt));
EXPECT_GT(rtt, 0);
}
} // namespace weblayer
// Copyright 2020 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 "weblayer/browser/client_hints_factory.h"
#include "components/client_hints/browser/client_hints.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/content_browser_client_impl.h"
#include "weblayer/browser/host_content_settings_map_factory.h"
namespace weblayer {
// static
client_hints::ClientHints* ClientHintsFactory::GetForBrowserContext(
content::BrowserContext* browser_context) {
return static_cast<client_hints::ClientHints*>(
GetInstance()->GetServiceForBrowserContext(browser_context, true));
}
// static
ClientHintsFactory* ClientHintsFactory::GetInstance() {
static base::NoDestructor<ClientHintsFactory> factory;
return factory.get();
}
ClientHintsFactory::ClientHintsFactory()
: BrowserContextKeyedServiceFactory(
"ClientHints",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(HostContentSettingsMapFactory::GetInstance());
}
ClientHintsFactory::~ClientHintsFactory() = default;
KeyedService* ClientHintsFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new client_hints::ClientHints(
context, BrowserProcess::GetInstance()->GetNetworkQualityTracker(),
HostContentSettingsMapFactory::GetForBrowserContext(context),
GetUserAgentMetadata());
}
content::BrowserContext* ClientHintsFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
return context;
}
} // namespace weblayer
// Copyright 2020 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 WEBLAYER_BROWSER_CLIENT_HINTS_FACTORY_H_
#define WEBLAYER_BROWSER_CLIENT_HINTS_FACTORY_H_
#include "base/no_destructor.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace client_hints {
class ClientHints;
}
namespace weblayer {
class ClientHintsFactory : public BrowserContextKeyedServiceFactory {
public:
ClientHintsFactory(const ClientHintsFactory&) = delete;
ClientHintsFactory& operator=(const ClientHintsFactory&) = delete;
static client_hints::ClientHints* GetForBrowserContext(
content::BrowserContext* browser_context);
static ClientHintsFactory* GetInstance();
private:
friend class base::NoDestructor<ClientHintsFactory>;
ClientHintsFactory();
~ClientHintsFactory() override;
// BrowserContextKeyedServiceFactory methods:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* profile) const override;
content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override;
};
} // namespace weblayer
#endif // WEBLAYER_BROWSER_CLIENT_HINTS_FACTORY_H_
......@@ -188,6 +188,19 @@ void CreateMediaDrmStorage(
namespace weblayer {
blink::UserAgentMetadata GetUserAgentMetadata() {
blink::UserAgentMetadata metadata;
metadata.brand = version_info::GetProductName();
metadata.full_version = version_info::GetVersionNumber();
metadata.major_version = version_info::GetMajorVersionNumber();
metadata.platform = version_info::GetOSType();
metadata.architecture = content::BuildCpuInfo();
metadata.model = content::BuildModelInfo();
return metadata;
}
ContentBrowserClientImpl::ContentBrowserClientImpl(MainParams* params)
: params_(params),
feature_list_creator_(std::make_unique<FeatureListCreator>()) {
......@@ -260,16 +273,7 @@ std::string ContentBrowserClientImpl::GetUserAgent() {
}
blink::UserAgentMetadata ContentBrowserClientImpl::GetUserAgentMetadata() {
blink::UserAgentMetadata metadata;
metadata.brand = version_info::GetProductName();
metadata.full_version = version_info::GetVersionNumber();
metadata.major_version = version_info::GetMajorVersionNumber();
metadata.platform = version_info::GetOSType();
metadata.architecture = content::BuildCpuInfo();
metadata.model = content::BuildModelInfo();
return metadata;
return weblayer::GetUserAgentMetadata();
}
void ContentBrowserClientImpl::OverrideWebkitPrefs(
......
......@@ -21,6 +21,8 @@ class FeatureListCreator;
class SafeBrowsingService;
struct MainParams;
blink::UserAgentMetadata GetUserAgentMetadata();
class ContentBrowserClientImpl : public content::ContentBrowserClient {
public:
explicit ContentBrowserClientImpl(MainParams* params);
......
......@@ -12,6 +12,7 @@
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/autofill_provider.h"
#include "components/captive_portal/core/buildflags.h"
#include "components/client_hints/browser/client_hints.h"
#include "components/find_in_page/find_tab_helper.h"
#include "components/find_in_page/find_types.h"
#include "components/permissions/permission_manager.h"
......@@ -31,7 +32,10 @@
#include "ui/base/window_open_disposition.h"
#include "weblayer/browser/autofill_client_impl.h"
#include "weblayer/browser/browser_impl.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/content_browser_client_impl.h"
#include "weblayer/browser/file_select_helper.h"
#include "weblayer/browser/host_content_settings_map_factory.h"
#include "weblayer/browser/i18n_util.h"
#include "weblayer/browser/isolated_world_ids.h"
#include "weblayer/browser/navigation_controller_impl.h"
......@@ -208,6 +212,12 @@ TabImpl::TabImpl(ProfileImpl* profile,
permissions::PermissionRequestManager::CreateForWebContents(
web_contents_.get());
client_hints::ClientHints::CreateForWebContents(
web_contents_.get(),
BrowserProcess::GetInstance()->GetNetworkQualityTracker(),
HostContentSettingsMapFactory::GetForBrowserContext(
web_contents_->GetBrowserContext()),
GetUserAgentMetadata());
#if defined(OS_ANDROID)
javascript_dialogs::TabModalDialogManager::CreateForWebContents(
......
......@@ -2,6 +2,7 @@ include_rules = [
"+components/android_system_error_page",
"+components/autofill/content/renderer",
"+components/cdm/renderer",
"+components/content_settings/renderer",
"+components/safe_browsing/content/common",
"+components/safe_browsing/content/renderer",
"+components/safe_browsing/core/common",
......
......@@ -8,6 +8,7 @@
#include "build/build_config.h"
#include "components/autofill/content/renderer/autofill_agent.h"
#include "components/autofill/content/renderer/password_autofill_agent.h"
#include "components/content_settings/renderer/content_settings_agent_impl.h"
#include "content/public/renderer/render_thread.h"
#include "third_party/blink/public/platform/platform.h"
#include "weblayer/common/features.h"
......@@ -78,6 +79,9 @@ void ContentRendererClientImpl::RenderFrameCreated(
render_frame, render_frame_observer->associated_interfaces());
new autofill::AutofillAgent(render_frame, password_autofill_agent, nullptr,
render_frame_observer->associated_interfaces());
new content_settings::ContentSettingsAgentImpl(
render_frame, false /* should_whitelist */,
std::make_unique<content_settings::ContentSettingsAgentImpl::Delegate>());
#if defined(OS_ANDROID)
// |SpellCheckProvider| manages its own lifetime (and destroys itself when the
......
......@@ -105,6 +105,7 @@ test("weblayer_browsertests") {
sources = [
"../browser/autofill_browsertest.cc",
"../browser/client_hints_browsertest.cc",
"../browser/cookie_manager_browsertest.cc",
"../browser/download_browsertest.cc",
"../browser/errorpage_browsertest.cc",
......
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