blob: 06eb1fe3723cf8df8d1edac6548254562c59aebc [file] [log] [blame]
// Copyright 2018 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/metrics/chrome_feature_list_creator.h"
#include <set>
#include "base/base_switches.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/path_service.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/switches.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/metrics/chrome_metrics_services_manager_client.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/chrome_pref_service_factory.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "components/flags_ui/flags_ui_pref_names.h"
#include "components/flags_ui/pref_service_flags_storage.h"
#include "components/language/core/browser/pref_names.h"
#include "components/metrics/clean_exit_beacon.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
#include "components/policy/core/common/policy_service.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service_factory.h"
#include "components/variations/pref_names.h"
#include "components/variations/service/variations_service.h"
#include "components/variations/variations_crash_keys.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/dbus/dbus_helper.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#endif
ChromeFeatureListCreator::ChromeFeatureListCreator() = default;
ChromeFeatureListCreator::~ChromeFeatureListCreator() = default;
void ChromeFeatureListCreator::CreateFeatureList() {
CreatePrefService();
ConvertFlagsToSwitches();
CreateMetricsServices();
SetupFieldTrials();
}
metrics_services_manager::MetricsServicesManagerClient*
ChromeFeatureListCreator::GetMetricsServicesManagerClient() {
return metrics_services_manager_client_;
}
std::unique_ptr<PrefService> ChromeFeatureListCreator::TakePrefService() {
return std::move(local_state_);
}
std::unique_ptr<metrics_services_manager::MetricsServicesManager>
ChromeFeatureListCreator::TakeMetricsServicesManager() {
return std::move(metrics_services_manager_);
}
std::unique_ptr<policy::ChromeBrowserPolicyConnector>
ChromeFeatureListCreator::TakeChromeBrowserPolicyConnector() {
return std::move(browser_policy_connector_);
}
std::unique_ptr<prefs::InProcessPrefServiceFactory>
ChromeFeatureListCreator::TakePrefServiceFactory() {
return std::move(pref_service_factory_);
}
void ChromeFeatureListCreator::CreatePrefService() {
base::FilePath local_state_file;
bool result =
base::PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_file);
DCHECK(result);
auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
RegisterLocalState(pref_registry.get());
#if defined(OS_CHROMEOS)
chromeos::PreEarlyInitDBus();
browser_policy_connector_ =
std::make_unique<policy::BrowserPolicyConnectorChromeOS>();
#else
browser_policy_connector_ =
std::make_unique<policy::ChromeBrowserPolicyConnector>();
#endif // defined(OS_CHROMEOS)
pref_service_factory_ =
std::make_unique<prefs::InProcessPrefServiceFactory>();
auto delegate = pref_service_factory_->CreateDelegate();
delegate->InitPrefRegistry(pref_registry.get());
local_state_ = chrome_prefs::CreateLocalState(
local_state_file, browser_policy_connector_->GetPolicyService(),
std::move(pref_registry), false, std::move(delegate),
browser_policy_connector_.get());
}
void ChromeFeatureListCreator::ConvertFlagsToSwitches() {
#if !defined(OS_CHROMEOS)
// Convert active flags into switches. This needs to be done before
// ui::ResourceBundle::InitSharedInstanceWithLocale as some loaded resources
// are affected by experiment flags (--touch-optimized-ui in particular). On
// ChromeOS system level flags are applied from the device settings from the
// session manager.
DCHECK(!ui::ResourceBundle::HasSharedInstance());
TRACE_EVENT0("startup", "ChromeFeatureListCreator::ConvertFlagsToSwitches");
flags_ui::PrefServiceFlagsStorage flags_storage(local_state_.get());
about_flags::ConvertFlagsToSwitches(&flags_storage,
base::CommandLine::ForCurrentProcess(),
flags_ui::kAddSentinels);
#endif // !defined(OS_CHROMEOS)
}
void ChromeFeatureListCreator::SetupFieldTrials() {
browser_field_trials_ = std::make_unique<ChromeBrowserFieldTrials>();
// Initialize FieldTrialList to support FieldTrials. 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.
base::FieldTrialList* leaked_field_trial_list = new base::FieldTrialList(
metrics_services_manager_.get()->CreateEntropyProvider());
ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list);
ignore_result(leaked_field_trial_list);
auto feature_list = std::make_unique<base::FeatureList>();
// Associate parameters chosen in about:flags and create trial/group for them.
flags_ui::PrefServiceFlagsStorage flags_storage(local_state_.get());
std::vector<std::string> variation_ids =
about_flags::RegisterAllFeatureVariationParameters(&flags_storage,
feature_list.get());
std::set<std::string> unforceable_field_trials;
#if defined(OFFICIAL_BUILD)
unforceable_field_trials.insert("SettingsEnforcement");
#endif // defined(OFFICIAL_BUILD)
variations::VariationsService* variations_service =
metrics_services_manager_.get()->GetVariationsService();
variations_service->SetupFieldTrials(
cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
switches::kDisableFeatures, unforceable_field_trials, variation_ids,
std::move(feature_list), browser_field_trials_.get());
variations::InitCrashKeys();
// Initialize FieldTrialSynchronizer system, which is used to synchronize
// field trial state with child process.
field_trial_synchronizer_ = base::MakeRefCounted<FieldTrialSynchronizer>();
}
void ChromeFeatureListCreator::CreateMetricsServices() {
auto client =
std::make_unique<ChromeMetricsServicesManagerClient>(local_state_.get());
metrics_services_manager_client_ = client.get();
metrics_services_manager_ =
std::make_unique<metrics_services_manager::MetricsServicesManager>(
std::move(client));
}