Commit a0e799c6 authored by Paul Miller's avatar Paul Miller Committed by Commit Bot

Create WebView's prefs earlier and use them for variations

Google-internal design doc:
https://docs.google.com/document/d/1X6Xoz9hl3qoAj3EhAKcvZ6hWLVcY_QpQgmUexpgDHKA/edit?usp=sharing

Move prefs creation from AwBrowserContext in PreMainMessageLoopRun to
AwBrowserMainParts in PreCreateThreads. This way, variations can use the
same pref service as the rest of WebView, while still being initialized
as early as possible. (See BrowserMainLoop::CreateStartupTasks() for an
overview of the startup sequence.)

Before, AwBrowserContext created and owned PrefService and
BrowserPolicyConnector. Now, AwBrowserMainParts creates them in
PreCreateThreads, and owns them until PreMainMessageLoopRun, at which
point ownership is transferred to AwBrowserContext.

BUG=866722

Change-Id: Ie8eb6df60bd4a0f872d8c6401cc14ff0bca38368
Reviewed-on: https://chromium-review.googlesource.com/1212268Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Commit-Queue: Paul Miller <paulmiller@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589665}
parent 40d837ca
......@@ -725,6 +725,7 @@ source_set("common") {
"//components/keyed_service/content",
"//components/metrics",
"//components/metrics:gpu",
"//components/metrics:metrics",
"//components/metrics:net",
"//components/metrics:ui",
"//components/minidump_uploader",
......
......@@ -5,9 +5,9 @@
#include "android_webview/browser/aw_browser_context.h"
#include <memory>
#include <string>
#include <utility>
#include "android_webview/browser/aw_browser_policy_connector.h"
#include "android_webview/browser/aw_download_manager_delegate.h"
#include "android_webview/browser/aw_form_database_service.h"
#include "android_webview/browser/aw_metrics_service_client.h"
......@@ -17,23 +17,13 @@
#include "android_webview/browser/aw_safe_browsing_whitelist_manager.h"
#include "android_webview/browser/aw_web_ui_controller_factory.h"
#include "android_webview/browser/net/aw_url_request_context_getter.h"
#include "android_webview/common/aw_content_client.h"
#include "base/base_paths_android.h"
#include "base/base_paths_posix.h"
#include "base/bind.h"
#include "base/path_service.h"
#include "base/single_thread_task_runner.h"
#include "base/task/post_task.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/metrics/metrics_service.h"
#include "components/policy/core/browser/browser_policy_connector_base.h"
#include "components/policy/core/browser/configuration_policy_pref_store.h"
#include "components/policy/core/browser/url_blacklist_manager.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/safe_browsing/common/safe_browsing_prefs.h"
#include "components/safe_browsing/triggers/trigger_manager.h"
#include "components/url_formatter/url_fixer.h"
#include "components/user_prefs/user_prefs.h"
......@@ -71,17 +61,6 @@ const base::FilePath::CharType kChannelIDFilename[] = "Origin Bound Certs";
const void* const kDownloadManagerDelegateKey = &kDownloadManagerDelegateKey;
// Shows notifications which correspond to PersistentPrefStore's reading errors.
void HandleReadError(PersistentPrefStore::PrefReadError error) {
}
base::FilePath GetPrefStorePath() {
base::FilePath path;
base::PathService::Get(base::DIR_ANDROID_APP_DATA, &path);
path = path.Append(FILE_PATH_LITERAL("pref_store"));
return path;
}
AwBrowserContext* g_browser_context = NULL;
std::unique_ptr<net::ProxyConfigServiceAndroid> CreateProxyConfigService() {
......@@ -118,12 +97,20 @@ base::FilePath GetCacheDirForAw() {
} // namespace
AwBrowserContext::AwBrowserContext(const FilePath path)
: context_storage_path_(path) {
AwBrowserContext::AwBrowserContext(
const base::FilePath path,
std::unique_ptr<PrefService> pref_service,
std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector)
: context_storage_path_(path),
user_pref_service_(std::move(pref_service)),
browser_policy_connector_(std::move(policy_connector)) {
DCHECK(!g_browser_context);
g_browser_context = this;
BrowserContext::Initialize(this, path);
pref_change_registrar_.Init(user_pref_service_.get());
user_prefs::UserPrefs::Set(this, user_pref_service_.get());
// This constructor is entered during the creation of ContentBrowserClient,
// before browser threads are created. Therefore any checks to enforce
// threading (such as BrowserThread::CurrentlyOn()) will fail here.
......@@ -151,10 +138,6 @@ AwBrowserContext* AwBrowserContext::FromWebContents(
void AwBrowserContext::PreMainMessageLoopRun(net::NetLog* net_log) {
FilePath cache_path = GetCacheDirForAw();
browser_policy_connector_.reset(new AwBrowserPolicyConnector());
InitUserPrefService();
url_request_context_getter_ = new AwURLRequestContextGetter(
cache_path, context_storage_path_.Append(kChannelIDFilename),
CreateProxyConfigService(), user_pref_service_.get(), net_log);
......@@ -226,58 +209,6 @@ AwURLRequestContextGetter* AwBrowserContext::GetAwURLRequestContext() {
return url_request_context_getter_.get();
}
// Create user pref service
void AwBrowserContext::InitUserPrefService() {
auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
// We only use the autocomplete feature of Autofill, which is controlled via
// the manager_delegate. We don't use the rest of Autofill, which is why it is
// hardcoded as disabled here.
// TODO(crbug.com/873740): The following also disables autocomplete.
// Investigate what the intended behavior is.
pref_registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled,
false);
pref_registry->RegisterBooleanPref(
autofill::prefs::kAutofillCreditCardEnabled, false);
policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry.get());
pref_registry->RegisterStringPref(prefs::kWebRestrictionsAuthority,
std::string());
android_webview::AwURLRequestContextGetter::RegisterPrefs(
pref_registry.get());
metrics::MetricsService::RegisterPrefs(pref_registry.get());
safe_browsing::RegisterProfilePrefs(pref_registry.get());
PrefServiceFactory pref_service_factory;
// These prefs go in the JsonPrefStore, and will persist across runs. Other
// prefs go in the InMemoryPrefStore, and will be lost when the process ends.
std::set<std::string> persistent_prefs;
// TODO(crbug/866722): Add kMetricsLowEntropySource to persistent_prefs to
// support persistent variations experiments.
// SegregatedPrefStore may be validated with a MAC (message authentication
// code). On Android, the store is protected by app sandboxing, so validation
// is unnnecessary. Thus validation_delegate is null.
pref_service_factory.set_user_prefs(
base::MakeRefCounted<SegregatedPrefStore>(
base::MakeRefCounted<InMemoryPrefStore>(),
base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()),
persistent_prefs, /*validation_delegate=*/nullptr));
pref_service_factory.set_managed_prefs(
base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>(
browser_policy_connector_.get(),
browser_policy_connector_->GetPolicyService(),
browser_policy_connector_->GetHandlerList(),
policy::POLICY_LEVEL_MANDATORY));
pref_service_factory.set_read_error_callback(
base::BindRepeating(&HandleReadError));
user_pref_service_ = pref_service_factory.Create(pref_registry);
pref_change_registrar_.Init(user_pref_service_.get());
user_prefs::UserPrefs::Set(this, user_pref_service_.get());
}
base::FilePath AwBrowserContext::GetPath() const {
return context_storage_path_;
}
......
......@@ -65,7 +65,10 @@ extern const char kWebRestrictionsAuthority[];
class AwBrowserContext : public content::BrowserContext,
public visitedlink::VisitedLinkDelegate {
public:
AwBrowserContext(const base::FilePath path);
AwBrowserContext(
const base::FilePath path,
std::unique_ptr<PrefService> pref_service,
std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector);
~AwBrowserContext() override;
// Currently only one instance per process is supported.
......@@ -126,7 +129,6 @@ class AwBrowserContext : public content::BrowserContext,
AwSafeBrowsingWhitelistManager* GetSafeBrowsingWhitelistManager() const;
private:
void InitUserPrefService();
void OnWebRestrictionsAuthorityChanged();
// The file path where data for this context is persisted.
......
......@@ -5,12 +5,17 @@
#include "android_webview/browser/aw_browser_main_parts.h"
#include <memory>
#include <set>
#include <string>
#include <utility>
#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_browser_policy_connector.h"
#include "android_webview/browser/aw_browser_terminator.h"
#include "android_webview/browser/aw_content_browser_client.h"
#include "android_webview/browser/aw_metrics_service_client.h"
#include "android_webview/browser/net/aw_network_change_notifier_factory.h"
#include "android_webview/browser/net/aw_url_request_context_getter.h"
#include "android_webview/common/aw_descriptors.h"
#include "android_webview/common/aw_paths.h"
#include "android_webview/common/aw_resource.h"
......@@ -20,16 +25,27 @@
#include "base/android/build_info.h"
#include "base/android/locale_utils.h"
#include "base/android/memory_pressure_listener_android.h"
#include "base/base_paths_android.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/i18n/rtl.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h"
#include "base/path_service.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
#include "components/crash/content/browser/crash_dump_manager_android.h"
#include "components/heap_profiling/supervisor.h"
#include "components/metrics/metrics_service.h"
#include "components/policy/core/browser/configuration_policy_pref_store.h"
#include "components/policy/core/browser/url_blacklist_manager.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_service_factory.h"
#include "components/services/heap_profiling/public/cpp/settings.h"
#include "components/user_prefs/user_prefs.h"
#include "components/variations/service/variations_service.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
......@@ -40,6 +56,7 @@
#include "content/public/common/service_names.mojom.h"
#include "net/android/network_change_notifier_factory_android.h"
#include "net/base/network_change_notifier.h"
#include "services/preferences/tracked/segregated_pref_store.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/layout.h"
......@@ -48,6 +65,71 @@
#include "ui/base/ui_base_paths.h"
#include "ui/gl/gl_surface.h"
namespace {
// Shows notifications which correspond to PersistentPrefStore's reading errors.
void HandleReadError(PersistentPrefStore::PrefReadError error) {}
base::FilePath GetPrefStorePath() {
base::FilePath path;
base::PathService::Get(base::DIR_ANDROID_APP_DATA, &path);
path = path.Append(FILE_PATH_LITERAL("pref_store"));
return path;
}
std::unique_ptr<PrefService> CreatePrefService(
policy::BrowserPolicyConnectorBase* browser_policy_connector) {
auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
// We only use the autocomplete feature of Autofill, which is controlled via
// the manager_delegate. We don't use the rest of Autofill, which is why it is
// hardcoded as disabled here.
// TODO(crbug.com/873740): The following also disables autocomplete.
// Investigate what the intended behavior is.
pref_registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled,
false);
pref_registry->RegisterBooleanPref(
autofill::prefs::kAutofillCreditCardEnabled, false);
policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry.get());
pref_registry->RegisterStringPref(
android_webview::prefs::kWebRestrictionsAuthority, std::string());
android_webview::AwURLRequestContextGetter::RegisterPrefs(
pref_registry.get());
metrics::MetricsService::RegisterPrefs(pref_registry.get());
variations::VariationsService::RegisterPrefs(pref_registry.get());
safe_browsing::RegisterProfilePrefs(pref_registry.get());
PrefServiceFactory pref_service_factory;
// These prefs go in the JsonPrefStore, and will persist across runs. Other
// prefs go in the InMemoryPrefStore, and will be lost when the process ends.
std::set<std::string> persistent_prefs;
// TODO(crbug/866722): Add kMetricsLowEntropySource to persistent_prefs to
// support persistent variations experiments.
// SegregatedPrefStore may be validated with a MAC (message authentication
// code). On Android, the store is protected by app sandboxing, so validation
// is unnnecessary. Thus validation_delegate is null.
pref_service_factory.set_user_prefs(
base::MakeRefCounted<SegregatedPrefStore>(
base::MakeRefCounted<InMemoryPrefStore>(),
base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()),
persistent_prefs, /*validation_delegate=*/nullptr));
pref_service_factory.set_managed_prefs(
base::MakeRefCounted<policy::ConfigurationPolicyPrefStore>(
browser_policy_connector,
browser_policy_connector->GetPolicyService(),
browser_policy_connector->GetHandlerList(),
policy::POLICY_LEVEL_MANDATORY));
pref_service_factory.set_read_error_callback(
base::BindRepeating(&HandleReadError));
return pref_service_factory.Create(pref_registry);
}
} // namespace
namespace android_webview {
AwBrowserMainParts::AwBrowserMainParts(AwContentBrowserClient* browser_client)
......@@ -129,14 +211,19 @@ int AwBrowserMainParts::PreCreateThreads() {
std::make_unique<AwBrowserTerminator>(crash_dir));
}
aw_field_trial_creator_.SetUpFieldTrials();
browser_policy_connector_ = std::make_unique<AwBrowserPolicyConnector>();
pref_service_ = CreatePrefService(browser_policy_connector_.get());
aw_field_trial_creator_.SetUpFieldTrials(pref_service_.get());
return service_manager::RESULT_CODE_NORMAL_EXIT;
}
void AwBrowserMainParts::PreMainMessageLoopRun() {
browser_client_->InitBrowserContext()->PreMainMessageLoopRun(
browser_client_->GetNetLog());
DCHECK(pref_service_);
DCHECK(browser_policy_connector_);
AwBrowserContext* context = browser_client_->InitBrowserContext(
std::move(pref_service_), std::move(browser_policy_connector_));
context->PreMainMessageLoopRun(browser_client_->GetNetLog());
content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
}
......
......@@ -16,6 +16,10 @@ namespace base {
class MessageLoop;
}
namespace policy {
class BrowserPolicyConnectorBase;
}
namespace android_webview {
class AwContentBrowserClient;
......@@ -38,6 +42,11 @@ class AwBrowserMainParts : public content::BrowserMainParts {
// Android specific UI MessageLoop.
std::unique_ptr<base::MessageLoop> main_message_loop_;
// Created and temporarily owned by AwBrowserMainParts
// until ownership is transferred to AwBrowserContext.
std::unique_ptr<PrefService> pref_service_;
std::unique_ptr<policy::BrowserPolicyConnectorBase> browser_policy_connector_;
AwContentBrowserClient* browser_client_;
// Responsible for creating a feature list from the seed. This object must
......
......@@ -4,6 +4,7 @@
#include "android_webview/browser/aw_content_browser_client.h"
#include <string>
#include <utility>
#include <vector>
......@@ -45,6 +46,7 @@
#include "components/crash/content/browser/child_exit_observer_android.h"
#include "components/navigation_interception/intercept_navigation_delegate.h"
#include "components/policy/content/policy_blacklist_navigation_throttle.h"
#include "components/policy/core/browser/browser_policy_connector_base.h"
#include "components/safe_browsing/browser/browser_url_loader_throttle.h"
#include "components/safe_browsing/browser/mojo_safe_browsing_impl.h"
#include "components/safe_browsing/features.h"
......@@ -214,12 +216,15 @@ AwContentBrowserClient::AwContentBrowserClient() : net_log_(new net::NetLog()) {
AwContentBrowserClient::~AwContentBrowserClient() {}
AwBrowserContext* AwContentBrowserClient::InitBrowserContext() {
AwBrowserContext* AwContentBrowserClient::InitBrowserContext(
std::unique_ptr<PrefService> pref_service,
std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector) {
base::FilePath user_data_dir;
if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) {
NOTREACHED() << "Failed to get app data directory for Android WebView";
}
browser_context_.reset(new AwBrowserContext(user_data_dir));
browser_context_ = std::make_unique<AwBrowserContext>(
user_data_dir, std::move(pref_service), std::move(policy_connector));
return browser_context_.get();
}
......
......@@ -8,6 +8,8 @@
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
......@@ -15,6 +17,8 @@
#include "content/public/browser/content_browser_client.h"
#include "services/service_manager/public/cpp/binder_registry.h"
class PrefService;
namespace content {
class RenderFrameHost;
}
......@@ -23,6 +27,10 @@ namespace net {
class NetLog;
}
namespace policy {
class BrowserPolicyConnectorBase;
}
namespace safe_browsing {
class UrlCheckerDelegate;
}
......@@ -44,7 +52,9 @@ class AwContentBrowserClient : public content::ContentBrowserClient {
// Allows AwBrowserMainParts to initialize a BrowserContext at the right
// moment during startup. AwContentBrowserClient owns the result.
AwBrowserContext* InitBrowserContext();
AwBrowserContext* InitBrowserContext(
std::unique_ptr<PrefService> pref_service,
std::unique_ptr<policy::BrowserPolicyConnectorBase> policy_connector);
content::BrowserMainParts* CreateBrowserMainParts(
const content::MainFunctionParams& parameters) override;
......
......@@ -19,15 +19,11 @@
#include "base/strings/string_split.h"
#include "base/time/time.h"
#include "cc/base/switches.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/pref_names.h"
#include "components/variations/seed_response.h"
#include "components/variations/service/safe_seed_manager.h"
#include "components/variations/service/variations_service.h"
namespace android_webview {
namespace {
......@@ -49,8 +45,8 @@ AwFieldTrialCreator::AwFieldTrialCreator()
AwFieldTrialCreator::~AwFieldTrialCreator() {}
void AwFieldTrialCreator::SetUpFieldTrials() {
DoSetUpFieldTrials();
void AwFieldTrialCreator::SetUpFieldTrials(PrefService* pref_service) {
DoSetUpFieldTrials(pref_service);
// If DoSetUpFieldTrials failed, it might have skipped creating
// FeatureList. If so, create a FeatureList without field trials.
......@@ -65,7 +61,7 @@ void AwFieldTrialCreator::SetUpFieldTrials() {
}
}
void AwFieldTrialCreator::DoSetUpFieldTrials() {
void AwFieldTrialCreator::DoSetUpFieldTrials(PrefService* pref_service) {
// If the client ID isn't available yet, don't delay startup by creating it.
// Instead, variations will be disabled for this run.
std::string client_id;
......@@ -80,7 +76,7 @@ void AwFieldTrialCreator::DoSetUpFieldTrials() {
client_ = std::make_unique<AwVariationsServiceClient>();
variations_field_trial_creator_ =
std::make_unique<variations::VariationsFieldTrialCreator>(
GetLocalState(), client_.get(), ui_string_overrider,
pref_service, client_.get(), ui_string_overrider,
GetAndClearJavaSeed());
variations_field_trial_creator_->OverrideVariationsPlatform(
variations::Study::PLATFORM_ANDROID_WEBVIEW);
......@@ -90,7 +86,7 @@ void AwFieldTrialCreator::DoSetUpFieldTrials() {
// TODO(isherman): We might want a more genuine SafeSeedManager:
// https://crbug.com/801771
std::set<std::string> unforceable_field_trials;
variations::SafeSeedManager ignored_safe_seed_manager(true, GetLocalState());
variations::SafeSeedManager ignored_safe_seed_manager(true, pref_service);
// Populates the FieldTrialList singleton via the static member functions.
variations_field_trial_creator_->SetupFieldTrials(
cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
......@@ -100,17 +96,4 @@ void AwFieldTrialCreator::DoSetUpFieldTrials() {
&ignored_safe_seed_manager);
}
PrefService* AwFieldTrialCreator::GetLocalState() {
if (!local_state_) {
scoped_refptr<PrefRegistrySimple> pref_registry =
base::MakeRefCounted<PrefRegistrySimple>();
variations::VariationsService::RegisterPrefs(pref_registry.get());
PrefServiceFactory factory;
factory.set_user_prefs(base::MakeRefCounted<InMemoryPrefStore>());
local_state_ = factory.Create(pref_registry.get());
}
return local_state_.get();
}
} // namespace android_webview
......@@ -5,6 +5,8 @@
#ifndef ANDROID_WEBVIEW_BROWSER_AW_FIELD_TRIAL_CREATOR_H_
#define ANDROID_WEBVIEW_BROWSER_AW_FIELD_TRIAL_CREATOR_H_
#include <memory>
#include "android_webview/browser/aw_field_trials.h"
#include "android_webview/browser/aw_variations_service_client.h"
#include "base/metrics/field_trial.h"
......@@ -23,11 +25,10 @@ class AwFieldTrialCreator {
~AwFieldTrialCreator();
// Sets up the field trials and related initialization.
void SetUpFieldTrials();
void SetUpFieldTrials(PrefService* pref_service);
private:
void DoSetUpFieldTrials();
PrefService* GetLocalState();
void DoSetUpFieldTrials(PrefService* pref_service);
// Stores the seed. VariationsSeedStore keeps a raw pointer to this, so it
// must persist for the process lifetime. Not persisted accross runs.
......
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