| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "headless/lib/browser/headless_field_trials.h" |
| |
| #include <functional> |
| #include <memory> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/feature_list.h" |
| #include "components/metrics/enabled_state_provider.h" |
| #include "components/metrics/metrics_state_manager.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/variations/platform_field_trials.h" |
| #include "components/variations/seed_response.h" |
| #include "components/variations/service/safe_seed_manager.h" |
| #include "components/variations/service/ui_string_overrider.h" |
| #include "components/variations/service/variations_field_trial_creator.h" |
| #include "components/variations/service/variations_service_client.h" |
| #include "components/variations/variations_safe_seed_store_local_state.h" |
| #include "components/variations/variations_seed_store.h" |
| #include "components/variations/variations_switches.h" |
| #include "content/public/common/content_switch_dependent_feature_overrides.h" |
| #include "services/network/public/cpp/shared_url_loader_factory.h" |
| |
| namespace headless { |
| |
| namespace { |
| |
| // A simple concrete implementation of the EnabledStateProvider interface. |
| class HeadlessEnabledStateProvider : public metrics::EnabledStateProvider { |
| public: |
| HeadlessEnabledStateProvider(bool consent, bool enabled) |
| : consent_(consent), enabled_(enabled) {} |
| |
| HeadlessEnabledStateProvider(const HeadlessEnabledStateProvider&) = delete; |
| HeadlessEnabledStateProvider& operator=(const HeadlessEnabledStateProvider&) = |
| delete; |
| |
| ~HeadlessEnabledStateProvider() override = default; |
| |
| // metrics::EnabledStateProvider |
| bool IsConsentGiven() const override { return consent_; } |
| bool IsReportingEnabled() const override { return enabled_; } |
| |
| private: |
| bool consent_; |
| bool enabled_; |
| }; |
| |
| class HeadlessVariationsServiceClient |
| : public variations::VariationsServiceClient { |
| public: |
| HeadlessVariationsServiceClient() = default; |
| ~HeadlessVariationsServiceClient() override = default; |
| |
| // variations::VariationsServiceClient: |
| base::Version GetVersionForSimulation() override { return base::Version(); } |
| scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() |
| override { |
| return nullptr; |
| } |
| network_time::NetworkTimeTracker* GetNetworkTimeTracker() override { |
| return nullptr; |
| } |
| version_info::Channel GetChannel() override { |
| return version_info::Channel::UNKNOWN; |
| } |
| bool OverridesRestrictParameter(std::string* parameter) override { |
| return false; |
| } |
| bool IsEnterprise() override { return false; } |
| |
| void RemoveGoogleGroupsFromPrefsForDeletedProfiles( |
| PrefService* local_state) override {} |
| }; |
| |
| } // namespace |
| |
| bool ShouldEnableFieldTrials() { |
| static bool should_enable_field_trials = |
| base::CommandLine::ForCurrentProcess()->HasSwitch( |
| variations::switches::kEnableFieldTrialTestingConfig); |
| return should_enable_field_trials; |
| } |
| |
| void SetUpFieldTrials(PrefService* local_state, |
| const base::FilePath& user_data_dir) { |
| CHECK(local_state); |
| |
| HeadlessEnabledStateProvider enabled_state_provider(/*consent=*/false, |
| /*enabled=*/false); |
| |
| std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager = |
| metrics::MetricsStateManager::Create(local_state, &enabled_state_provider, |
| std::wstring(), user_data_dir); |
| |
| metrics_state_manager->InstantiateFieldTrialList(); |
| |
| HeadlessVariationsServiceClient variations_service_client; |
| variations::VariationsFieldTrialCreator field_trial_creator( |
| &variations_service_client, |
| std::make_unique<variations::VariationsSeedStore>( |
| local_state, /*initial_seed=*/nullptr, |
| /*signature_verification_enabled=*/true, |
| std::make_unique<variations::VariationsSafeSeedStoreLocalState>( |
| local_state, variations_service_client.GetVariationsSeedFileDir(), |
| variations_service_client.GetChannelForVariations(), |
| /*entropy_providers=*/nullptr), |
| variations_service_client.GetChannelForVariations(), |
| variations_service_client.GetVariationsSeedFileDir()), |
| variations::UIStringOverrider()); |
| |
| variations::SafeSeedManager safe_seed_manager(local_state); |
| |
| const base::CommandLine& command_line = |
| *base::CommandLine::ForCurrentProcess(); |
| |
| // Overrides for content/common and lower layers' switches. |
| std::vector<base::FeatureList::FeatureOverrideInfo> feature_overrides = |
| content::GetSwitchDependentFeatureOverrides(command_line); |
| |
| // Setup field trials directly without help of the variations service. |
| std::vector<std::string> variation_ids; |
| auto feature_list = std::make_unique<base::FeatureList>(); |
| variations::PlatformFieldTrials platform_field_trials; |
| field_trial_creator.SetUpFieldTrials( |
| variation_ids, |
| command_line.GetSwitchValueASCII( |
| variations::switches::kForceVariationIds), |
| feature_overrides, std::move(feature_list), metrics_state_manager.get(), |
| &platform_field_trials, &safe_seed_manager, |
| /*add_entropy_source_to_variations_ids=*/false, |
| *metrics_state_manager->CreateEntropyProviders( |
| /*enable_limited_entropy_mode=*/false)); |
| } |
| |
| } // namespace headless |