#include "components/variations/service/variations_service.h"
#include <stddef.h>
#include <stdint.h>
#include <optional>
#include <string_view>
#include <utility>
#include <vector>
#include "base/base64.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "base/version.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/encrypted_messages/encrypted_message.pb.h"
#include "components/encrypted_messages/message_encrypter.h"
#include "components/metrics/metrics_state_manager.h"
#include "components/network_time/network_time_tracker.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/variations/field_trial_internals_utils.h"
#include "components/variations/pref_names.h"
#include "components/variations/proto/variations_seed.pb.h"
#include "components/variations/seed_response.h"
#include "components/variations/service/limited_entropy_synthetic_trial.h"
#include "components/variations/synthetic_trial_registry.h"
#include "components/variations/variations_safe_seed_store_local_state.h"
#include "components/variations/variations_seed_simulator.h"
#include "components/variations/variations_switches.h"
#include "components/variations/variations_url_constants.h"
#include "components/version_info/channel.h"
#include "components/version_info/version_info.h"
#include "net/base/net_errors.h"
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "url/gurl.h"
namespace variations {
namespace {
const char kEncryptedMessageLabel[] = …;
const uint8_t kServerPublicKey[] = …;
const uint32_t kServerPublicKeyVersion = …;
const uint32_t kServerTimeResolutionInSeconds = …;
bool g_should_fetch_for_testing = …;
std::string GetPlatformString() { … }
std::string GetRestrictParameterValue(const std::string& restrict_mode_override,
VariationsServiceClient* client,
PrefService* policy_pref_service) { … }
enum ResourceRequestsAllowedState { … };
void RecordRequestsAllowedHistogram(ResourceRequestsAllowedState state) { … }
ResourceRequestsAllowedState ResourceRequestStateToHistogramValue(
web_resource::ResourceRequestAllowedNotifier::State state) { … }
std::string GetHeaderValue(const net::HttpResponseHeaders* headers,
std::string_view name) { … }
std::vector<std::string> GetHeaderValuesList(
const net::HttpResponseHeaders* headers,
std::string_view name) { … }
bool GetInstanceManipulations(const net::HttpResponseHeaders* headers,
bool* is_delta_compressed,
bool* is_gzip_compressed) { … }
bool IsFetchingEnabled() { … }
std::unique_ptr<SeedResponse> MaybeImportFirstRunSeed(
VariationsServiceClient* client,
PrefService* local_state) { … }
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
class DeviceVariationsRestrictionByPolicyApplicator {
public:
DeviceVariationsRestrictionByPolicyApplicator(
PrefService* policy_pref_service)
: policy_pref_service_(policy_pref_service) {
DCHECK(policy_pref_service_);
const PrefService::PrefInitializationStatus prefs_init_status =
policy_pref_service_->GetAllPrefStoresInitializationStatus();
if (prefs_init_status == PrefService::INITIALIZATION_STATUS_WAITING) {
policy_pref_service_->AddPrefInitObserver(
base::BindOnce(&DeviceVariationsRestrictionByPolicyApplicator::
OnPolicyPrefServiceInitialized,
weak_ptr_factory_.GetWeakPtr()));
return;
}
OnPolicyPrefServiceInitialized(prefs_init_status ==
PrefService::INITIALIZATION_STATUS_SUCCESS);
}
~DeviceVariationsRestrictionByPolicyApplicator() = default;
DeviceVariationsRestrictionByPolicyApplicator(
const DeviceVariationsRestrictionByPolicyApplicator& other) = delete;
DeviceVariationsRestrictionByPolicyApplicator& operator=(
const DeviceVariationsRestrictionByPolicyApplicator& other) = delete;
private:
void OnPolicyPrefServiceInitialized(bool successful) {
if (!successful)
return;
pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
pref_change_registrar_->Init(policy_pref_service_);
pref_change_registrar_->Add(
prefs::kDeviceVariationsRestrictionsByPolicy,
base::BindRepeating(&DeviceVariationsRestrictionByPolicyApplicator::
OnDevicePolicyChange,
weak_ptr_factory_.GetWeakPtr()));
OnDevicePolicyChange();
}
void OnDevicePolicyChange() {
const std::string& device_policy =
prefs::kDeviceVariationsRestrictionsByPolicy;
const std::string& user_policy = prefs::kVariationsRestrictionsByPolicy;
if (policy_pref_service_->IsManagedPreference(device_policy)) {
const int device_value = policy_pref_service_->GetInteger(device_policy);
policy_pref_service_->SetInteger(user_policy, device_value);
} else {
policy_pref_service_->ClearPref(user_policy);
}
}
const raw_ptr<PrefService> policy_pref_service_;
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
base::WeakPtrFactory<DeviceVariationsRestrictionByPolicyApplicator>
weak_ptr_factory_{this};
};
#endif
VariationsService::VariationsService(
std::unique_ptr<VariationsServiceClient> client,
std::unique_ptr<web_resource::ResourceRequestAllowedNotifier> notifier,
PrefService* local_state,
metrics::MetricsStateManager* state_manager,
const UIStringOverrider& ui_string_overrider,
SyntheticTrialRegistry* synthetic_trial_registry)
: … { … }
VariationsService::~VariationsService() = default;
void VariationsService::PerformPreMainMessageLoopStartup() { … }
std::string VariationsService::LoadPermanentConsistencyCountry(
const base::Version& version,
const std::string& latest_country) { … }
bool VariationsService::EncryptString(const std::string& plaintext,
std::string* encrypted) { … }
void VariationsService::AddObserver(Observer* observer) { … }
void VariationsService::RemoveObserver(Observer* observer) { … }
void VariationsService::OnAppEnterForeground() { … }
void VariationsService::SetRestrictMode(const std::string& restrict_mode) { … }
bool VariationsService::IsLikelyDogfoodClient() const { … }
void VariationsService::SetIsLikelyDogfoodClientForTesting(
bool is_dogfood_client) { … }
GURL VariationsService::GetVariationsServerURL(HttpOptions http_options) { … }
void VariationsService::EnsureLocaleEquals(const std::string& locale) { … }
std::string VariationsService::GetDefaultVariationsServerURLForTesting() { … }
void VariationsService::RegisterPrefs(PrefRegistrySimple* registry) { … }
void VariationsService::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) { … }
std::unique_ptr<VariationsService> VariationsService::Create(
std::unique_ptr<VariationsServiceClient> client,
PrefService* local_state,
metrics::MetricsStateManager* state_manager,
const char* disable_network_switch,
const UIStringOverrider& ui_string_overrider,
web_resource::ResourceRequestAllowedNotifier::NetworkConnectionTrackerGetter
network_connection_tracker_getter,
SyntheticTrialRegistry* synthetic_trial_registry) { … }
void VariationsService::EnableFetchForTesting() { … }
void VariationsService::DoActualFetch() { … }
const std::string& VariationsService::GetLatestSerialNumber() { … }
bool VariationsService::DoFetchFromURL(const GURL& url, bool is_http_retry) { … }
void VariationsService::StoreSeed(std::string seed_data,
std::string seed_signature,
std::string country_code,
base::Time date_fetched,
bool is_delta_compressed,
bool is_gzip_compressed) { … }
void VariationsService::OnSeedStoreResult(bool is_delta_compressed,
bool store_success,
VariationsSeed seed) { … }
void VariationsService::InitResourceRequestedAllowedNotifier() { … }
void VariationsService::StartRepeatedVariationsSeedFetch() { … }
void VariationsService::FetchVariationsSeed() { … }
void VariationsService::NotifyObservers(const SeedSimulationResult& result) { … }
void VariationsService::OnSimpleLoaderComplete(
std::unique_ptr<std::string> response_body) { … }
bool VariationsService::MaybeRetryOverHTTP() { … }
void VariationsService::OnResourceRequestsAllowed() { … }
void VariationsService::PerformSimulationWithVersion(
const VariationsSeed& seed,
const base::Version& version) { … }
bool VariationsService::CallMaybeRetryOverHTTPForTesting() { … }
void VariationsService::RecordSuccessfulFetch() { … }
std::unique_ptr<ClientFilterableState>
VariationsService::GetClientFilterableStateForVersion() { … }
std::string VariationsService::GetLatestCountry() const { … }
bool VariationsService::SetUpFieldTrials(
const std::vector<std::string>& variation_ids,
const std::string& command_line_variation_ids,
const std::vector<base::FeatureList::FeatureOverrideInfo>& extra_overrides,
std::unique_ptr<base::FeatureList> feature_list,
PlatformFieldTrials* platform_field_trials) { … }
std::vector<StudyGroupNames> VariationsService::GetStudiesAvailableToForce() { … }
SeedType VariationsService::GetSeedType() const { … }
void VariationsService::OverrideCachedUIStrings() { … }
void VariationsService::CancelCurrentRequestForTesting() { … }
void VariationsService::StartRepeatedVariationsSeedFetchForTesting() { … }
void VariationsService::OverridePlatform(
Study::Platform platform,
const std::string& osname_server_param_override) { … }
std::string VariationsService::GetOverriddenPermanentCountry() const { … }
std::string VariationsService::GetStoredPermanentCountry() const { … }
bool VariationsService::OverrideStoredPermanentCountry(
const std::string& country_override) { … }
}