910e62b5创建于 1月15日历史提交
// 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