blob: 2075e1ce7dc2c1c5b2e055ba886f5bcd6aaa807b [file] [log] [blame]
// 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 "weblayer/browser/feature_list_creator.h"
#include "base/base_switches.h"
#include "base/debug/leak_annotations.h"
#include "base/path_service.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_state_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_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "components/variations/pref_names.h"
#include "components/variations/service/ui_string_overrider.h"
#include "components/variations/variations_crash_keys.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_switch_dependent_feature_overrides.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
#include "weblayer/browser/system_network_context_manager.h"
#include "weblayer/browser/weblayer_variations_service_client.h"
#if defined(OS_ANDROID)
namespace switches {
const char kDisableBackgroundNetworking[] = "disable-background-networking";
} // namespace switches
#endif
namespace weblayer {
namespace {
void HandleReadError(PersistentPrefStore::PrefReadError error) {}
#if defined(OS_ANDROID)
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;
}
#endif
std::unique_ptr<PrefService> CreatePrefService() {
auto pref_registry = base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
#if defined(OS_ANDROID)
metrics::AndroidMetricsServiceClient::RegisterPrefs(pref_registry.get());
#endif
variations::VariationsService::RegisterPrefs(pref_registry.get());
PrefServiceFactory pref_service_factory;
#if defined(OS_ANDROID)
pref_service_factory.set_user_prefs(
base::MakeRefCounted<JsonPrefStore>(GetPrefStorePath()));
#else
// For now just use in memory PrefStore for desktop.
// TODO(weblayer-dev): Find a long term solution.
pref_service_factory.set_user_prefs(
base::MakeRefCounted<InMemoryPrefStore>());
#endif
pref_service_factory.set_read_error_callback(
base::BindRepeating(&HandleReadError));
return pref_service_factory.Create(pref_registry);
}
} // namespace
FeatureListCreator::FeatureListCreator() = default;
FeatureListCreator::~FeatureListCreator() = default;
void FeatureListCreator::SetSystemNetworkContextManager(
SystemNetworkContextManager* system_network_context_manager) {
system_network_context_manager_ = system_network_context_manager;
}
void FeatureListCreator::SetUpFieldTrials() {
#if defined(OS_ANDROID)
auto* metrics_client = WebLayerMetricsServiceClient::GetInstance();
// Initialize FieldTrialList to support FieldTrials. If an instance already
// exists, this is likely a test scenario with a ScopedFeatureList active,
// so use that one to apply any overrides.
if (!base::FieldTrialList::GetInstance()) {
// Note: This is intentionally leaked since it needs to live for the
// duration of the browser process and there's no benefit in cleaning it up
// at exit.
// Note: We deliberately use CreateLowEntropyProvider because
// CreateDefaultEntropyProvider needs to know if user conset has been given
// but getting consent from GMS is slow.
base::FieldTrialList* leaked_field_trial_list = new base::FieldTrialList(
metrics_client->metrics_state_manager()->CreateLowEntropyProvider());
ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list);
ignore_result(leaked_field_trial_list);
}
DCHECK(system_network_context_manager_);
variations_service_ = variations::VariationsService::Create(
std::make_unique<WebLayerVariationsServiceClient>(
system_network_context_manager_->GetSharedURLLoaderFactory()),
local_state_.get(), metrics_client->metrics_state_manager(),
switches::kDisableBackgroundNetworking, variations::UIStringOverrider(),
base::BindOnce(&content::GetNetworkConnectionTracker));
variations_service_->OverridePlatform(
variations::Study::PLATFORM_ANDROID_WEBLAYER, "android_weblayer");
std::set<std::string> unforceable_field_trials;
std::vector<std::string> variation_ids;
auto feature_list = std::make_unique<base::FeatureList>();
variations_service_->PerformPreMainMessageLoopStartup();
variations_service_->SetupFieldTrials(
cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
switches::kDisableFeatures, unforceable_field_trials, variation_ids,
content::GetSwitchDependentFeatureOverrides(
*base::CommandLine::ForCurrentProcess()),
std::move(feature_list), &weblayer_field_trials_);
variations::InitCrashKeys();
#else
// TODO(weblayer-dev): Support variations on desktop.
#endif
}
void FeatureListCreator::CreateFeatureListAndFieldTrials() {
local_state_ = CreatePrefService();
CHECK(local_state_);
#if defined(OS_ANDROID)
WebLayerMetricsServiceClient::GetInstance()->Initialize(local_state_.get());
#endif
SetUpFieldTrials();
}
} // namespace weblayer