#include "content/public/test/setup_field_trials.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "cc/base/switches.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/metrics/test/test_enabled_state_provider.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/platform_field_trials.h"
#include "components/variations/pref_names.h"
#include "components/variations/scoped_variations_ids_provider.h"
#include "components/variations/service/safe_seed_manager.h"
#include "components/variations/service/variations_field_trial_creator.h"
#include "components/variations/service/variations_service.h"
#include "components/variations/service/variations_service_client.h"
#include "components/variations/variations_ids_provider.h"
#include "components/variations/variations_safe_seed_store_local_state.h"
#include "components/variations/variations_switches.h"
#include "content/public/common/content_switch_dependent_feature_overrides.h"
#if BUILDFLAG(IS_ANDROID)
#include "components/variations/android/variations_seed_bridge.h"
#endif
namespace content {
namespace {
class VariationServiceClient : public variations::VariationsServiceClient {
public:
explicit VariationServiceClient(base::FilePath user_data_dir)
: user_data_dir_(std::move(user_data_dir)) {}
~VariationServiceClient() override = default;
VariationServiceClient(const VariationServiceClient&) = delete;
VariationServiceClient(VariationServiceClient&&) = delete;
VariationServiceClient& operator=(const VariationServiceClient&) = delete;
VariationServiceClient& operator=(VariationServiceClient&&) = delete;
base::Version GetVersionForSimulation() final { return base::Version(); }
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() final {
return nullptr;
}
network_time::NetworkTimeTracker* GetNetworkTimeTracker() final {
return nullptr;
}
version_info::Channel GetChannel() final {
return version_info::Channel::UNKNOWN;
}
bool OverridesRestrictParameter(std::string*) final { return false; }
base::FilePath GetVariationsSeedFileDir() final { return user_data_dir_; }
bool IsEnterprise() final { return false; }
void RemoveGoogleGroupsFromPrefsForDeletedProfiles(PrefService*) final {}
private:
base::FilePath user_data_dir_;
};
}
void SetupFieldTrials() {
const bool need_thread_pool = !base::ThreadPoolInstance::Get();
if (need_thread_pool) {
base::ThreadPoolInstance::Create("SetupFieldTrials");
}
base::ScopedTempDir user_data_dir;
CHECK(user_data_dir.CreateUniqueTempDir());
auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
metrics::MetricsService::RegisterPrefs(pref_registry.get());
variations::VariationsService::RegisterPrefs(pref_registry.get());
PrefServiceFactory factory;
factory.set_user_prefs(base::MakeRefCounted<InMemoryPrefStore>());
std::unique_ptr<PrefService> pref_service = factory.Create(pref_registry);
CHECK(pref_service);
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
std::vector<base::FeatureList::FeatureOverrideInfo> feature_overrides =
GetSwitchDependentFeatureOverrides(*command_line);
metrics::TestEnabledStateProvider enabled_state_provider(false,
false);
const bool force_benchmarking_mode =
command_line->HasSwitch(switches::kEnableGpuBenchmarking);
std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager =
metrics::MetricsStateManager::Create(
pref_service.get(), &enabled_state_provider, std::wstring(),
user_data_dir.GetPath(), metrics::StartupVisibility::kUnknown,
{
.force_benchmarking_mode = force_benchmarking_mode,
});
CHECK(metrics_state_manager);
metrics_state_manager->InstantiateFieldTrialList();
std::unique_ptr<variations::SeedResponse> initial_seed;
#if BUILDFLAG(IS_ANDROID)
if (!pref_service.get()->HasPrefPath(
variations::prefs::kVariationsSeedSignature)) {
DVLOG(1) << "Importing first run seed from Java preferences.";
initial_seed = variations::android::GetVariationsFirstRunSeed();
}
#endif
VariationServiceClient variations_service_client(user_data_dir.GetPath());
variations::VariationsFieldTrialCreator field_trial_creator(
&variations_service_client,
std::make_unique<variations::VariationsSeedStore>(
pref_service.get(), std::move(initial_seed),
true,
std::make_unique<variations::VariationsSafeSeedStoreLocalState>(
pref_service.get(),
variations_service_client.GetVariationsSeedFileDir(),
variations_service_client.GetChannelForVariations(),
nullptr),
variations_service_client.GetChannelForVariations(),
variations_service_client.GetVariationsSeedFileDir()),
variations::UIStringOverrider());
variations::SafeSeedManager safe_seed_manager(pref_service.get());
const std::vector<std::string> variation_ids;
const std::string command_line_variation_ids =
command_line->GetSwitchValueASCII(
variations::switches::kForceVariationIds);
auto feature_list = std::make_unique<base::FeatureList>();
variations::test::ScopedVariationsIdsProvider scoped_ids_provider(
variations::VariationsIdsProvider::Mode::kUseSignedInState);
variations::PlatformFieldTrials platform_field_trials;
field_trial_creator.SetUpFieldTrials(
variation_ids, command_line_variation_ids, feature_overrides,
std::move(feature_list), metrics_state_manager.get(),
&platform_field_trials, &safe_seed_manager,
false,
*metrics_state_manager->CreateEntropyProviders(
false));
if (need_thread_pool) {
base::ThreadPoolInstance::Get()->Start({1});
base::ThreadPoolInstance::Get()->Shutdown();
base::ThreadPoolInstance::Get()->JoinForTesting();
base::ThreadPoolInstance::Set(nullptr);
}
}
}