blob: 818078f461b44dcc34a28f929fa5b4688cab4c34 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/variations/cros/evaluate_seed.h"
#include "base/check.h"
#include "base/containers/flat_set.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/system/sys_info.h"
#include "build/branding_buildflags.h"
#include "chromeos/crosapi/cpp/channel_to_enum.h"
#include "chromeos/crosapi/cpp/crosapi_constants.h"
#include "components/variations/cros/featured.pb.h"
#include "components/variations/proto/study.pb.h"
#include "components/variations/service/variations_field_trial_creator.h"
namespace variations::evaluate_seed {
namespace {
constexpr char kSafeSeedSwitch[] = "use-safe-seed";
constexpr char kEnterpriseEnrolledSwitch[] = "enterprise-enrolled";
} // namespace
base::Version CrosVariationsServiceClient::GetVersionForSimulation() {
// TODO(mutexlox): Get the version that will be used on restart instead of
// the current version IF this is necessary. (We may not need simulations for
// early-boot experiments.)
// See ChromeVariationsServiceClient::GetVersionForSimulation.
return version_info::GetVersion();
}
scoped_refptr<network::SharedURLLoaderFactory>
CrosVariationsServiceClient::GetURLLoaderFactory() {
// Do not load any data on CrOS early boot. This function is only called to
// fetch a new seed, and we should not fetch new seeds in evaluate_seed.
return nullptr;
}
network_time::NetworkTimeTracker*
CrosVariationsServiceClient::GetNetworkTimeTracker() {
// Do not load any data on CrOS early boot; evaluate_seed should not load new
// seeds.
return nullptr;
}
bool CrosVariationsServiceClient::OverridesRestrictParameter(
std::string* parameter) {
// TODO(b/263975722): Implement.
return false;
}
// Get the active channel, if applicable.
version_info::Channel CrosVariationsServiceClient::GetChannel() {
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
std::string channel;
if (base::SysInfo::GetLsbReleaseValue(crosapi::kChromeOSReleaseTrack,
&channel)) {
return crosapi::ChannelToEnum(channel);
}
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
return version_info::Channel::UNKNOWN;
}
bool CrosVariationsServiceClient::IsEnterprise() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
kEnterpriseEnrolledSwitch);
}
std::unique_ptr<ClientFilterableState> GetClientFilterableState() {
CrosVariationsServiceClient client;
// TODO(b/263975722): Properly use VariationsServiceClient and
// VariationsFieldTrialCreator::GetClientFilterableStateForVersion.
auto state = std::make_unique<ClientFilterableState>(
base::BindOnce([](bool enrolled) { return enrolled; },
client.IsEnterprise()),
base::BindOnce([] { return base::flat_set<uint64_t>(); }));
state->channel =
ConvertProductChannelToStudyChannel(client.GetChannelForVariations());
state->form_factor = client.GetCurrentFormFactor();
return state;
}
absl::optional<SafeSeed> GetSafeSeedData(FILE* stream) {
featured::SeedDetails safe_seed;
if (base::CommandLine::ForCurrentProcess()->HasSwitch(kSafeSeedSwitch)) {
// Read safe seed from |stream|.
std::string safe_seed_data;
if (!base::ReadStreamToString(stream, &safe_seed_data)) {
PLOG(ERROR) << "Failed to read from stream:";
return absl::nullopt;
}
// Parse safe seed.
if (!safe_seed.ParseFromString(safe_seed_data)) {
LOG(ERROR) << "Failed to parse proto from input";
return absl::nullopt;
}
return SafeSeed{true, safe_seed};
}
return SafeSeed{false, safe_seed};
}
int EvaluateSeedMain(FILE* stream) {
absl::optional<SafeSeed> safe_seed = GetSafeSeedData(stream);
if (!safe_seed.has_value()) {
LOG(ERROR) << "Failed to read seed from stdin";
return EXIT_FAILURE;
}
std::unique_ptr<ClientFilterableState> state = GetClientFilterableState();
// TODO(b/263975722): Implement this binary.
(void)state;
return EXIT_SUCCESS;
}
} // namespace variations::evaluate_seed