| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chrome_browser_field_trials.h" |
| |
| #include <optional> |
| #include <string> |
| |
| #include "base/command_line.h" |
| #include "base/feature_list.h" |
| #include "base/files/file_util.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/path_service.h" |
| #include "base/strings/string_util.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/metrics/chrome_browser_sampling_trials.h" |
| #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" |
| #include "chrome/browser/metrics/chrome_metrics_service_client.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "components/metrics/metrics_pref_names.h" |
| #include "components/metrics/persistent_histograms.h" |
| #include "components/version_info/version_info.h" |
| |
| #if BUILDFLAG(IS_ANDROID) |
| #include "base/android/build_info.h" |
| #include "base/android/bundle_utils.h" |
| #include "base/task/thread_pool/environment_config.h" |
| #include "chrome/browser/android/flags/chrome_cached_flags.h" |
| #include "chrome/browser/flags/android/chrome_feature_list.h" |
| #include "chrome/common/chrome_features.h" |
| #endif |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| #include "chrome/common/channel_info.h" |
| #include "chromeos/ash/services/multidevice_setup/public/cpp/first_run_field_trial.h" |
| #endif |
| |
| #if BUILDFLAG(IS_LINUX) |
| #include "base/nix/xdg_util.h" |
| #include "ui/base/ui_base_features.h" |
| #endif // BUILDFLAG(IS_LINUX) |
| |
| ChromeBrowserFieldTrials::ChromeBrowserFieldTrials(PrefService* local_state) |
| : local_state_(local_state) { |
| DCHECK(local_state_); |
| } |
| |
| ChromeBrowserFieldTrials::~ChromeBrowserFieldTrials() = default; |
| |
| void ChromeBrowserFieldTrials::SetUpClientSideFieldTrials( |
| bool has_seed, |
| const variations::EntropyProviders& entropy_providers, |
| base::FeatureList* feature_list) { |
| // Only create the fallback trials if there isn't already a variations seed |
| // being applied. This should occur during first run when first-run variations |
| // isn't supported. It's assumed that, if there is a seed, then it either |
| // contains the relevant studies, or is intentionally omitted, so no fallback |
| // is needed. The exception is for sampling trials. Fallback trials are |
| // created even if no variations seed was applied. This allows testing the |
| // fallback code by intentionally omitting the sampling trial from a |
| // variations seed. |
| metrics::CreateFallbackSamplingTrialsIfNeeded( |
| entropy_providers.default_entropy(), feature_list); |
| metrics::CreateFallbackUkmSamplingTrialIfNeeded( |
| entropy_providers.default_entropy(), feature_list); |
| |
| #if BUILDFLAG(IS_CHROMEOS) |
| if (!has_seed) { |
| ash::multidevice_setup::CreateFirstRunFieldTrial(feature_list); |
| } |
| #endif |
| } |
| |
| void ChromeBrowserFieldTrials::RegisterSyntheticTrials() { |
| #if BUILDFLAG(IS_ANDROID) |
| { |
| // BackgroundThreadPoolSynthetic field trial. |
| const char* group_name; |
| // Target group as indicated by finch feature. |
| bool feature_enabled = |
| base::FeatureList::IsEnabled(chrome::android::kBackgroundThreadPool); |
| // Whether the feature was overridden by either the commandline or Finch. |
| bool feature_overridden = |
| base::FeatureList::GetInstance()->IsFeatureOverridden( |
| chrome::android::kBackgroundThreadPool.name); |
| // Whether the feature was overridden manually via the commandline. |
| bool cmdline_overridden = |
| feature_overridden && |
| base::FeatureList::GetInstance()->IsFeatureOverriddenFromCommandLine( |
| chrome::android::kBackgroundThreadPool.name); |
| // The finch feature value is cached by Java in a setting and applied via a |
| // command line flag. Check if this has happened -- it may not have happened |
| // if this is the first startup after the feature is enabled. |
| bool actually_enabled = |
| base::internal::CanUseBackgroundThreadTypeForWorkerThread(); |
| // Use the default group if either the feature wasn't overridden or if the |
| // feature target state and actual state don't agree. Also separate users |
| // that override the feature via the commandline into separate groups. |
| if (actually_enabled != feature_enabled || !feature_overridden) { |
| group_name = "Default"; |
| } else if (cmdline_overridden && feature_enabled) { |
| group_name = "ForceEnabled"; |
| } else if (cmdline_overridden && !feature_enabled) { |
| group_name = "ForceDisabled"; |
| } else if (feature_enabled) { |
| group_name = "Enabled"; |
| } else { |
| group_name = "Disabled"; |
| } |
| static constexpr char kBackgroundThreadPoolTrial[] = |
| "BackgroundThreadPoolSynthetic"; |
| ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial( |
| kBackgroundThreadPoolTrial, group_name); |
| } |
| #endif // BUILDFLAG(IS_ANDROID) |
| } |
| |
| #if BUILDFLAG(IS_LINUX) |
| // On Linux/Desktop platform variants, such as ozone/wayland, some features |
| // might need to be disabled as per OzonePlatform's runtime properties. |
| // OzonePlatform selection and initialization, in turn, depend on Chrome flags |
| // processing, namely 'ozone-platform-hint', so do it here. |
| // |
| // TODO(nickdiego): Move it back to ChromeMainDelegate::PostEarlyInitialization |
| // once ozone-platform-hint flag is dropped. |
| void ChromeBrowserFieldTrials::RegisterFeatureOverrides( |
| base::FeatureList* feature_list) { |
| std::unique_ptr<base::Environment> env = base::Environment::Create(); |
| std::string xdg_session_type = |
| env->GetVar(base::nix::kXdgSessionTypeEnvVar).value_or(std::string()); |
| |
| if (xdg_session_type == "wayland") { |
| feature_list->RegisterExtraFeatureOverrides( |
| {{features::kEyeDropper, base::FeatureList::OVERRIDE_DISABLE_FEATURE}}); |
| } |
| } |
| #endif // BUILDFLAG(IS_LINUX) |