blob: aa1e7432424a4e4c23e035c0e4ea0f09e03a1553 [file] [log] [blame]
// Copyright 2020 The Cobalt Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cobalt/updater/configurator.h"
#include <set>
#include <utility>
#include "base/command_line.h"
#include "base/version.h"
#include "cobalt/browser/switches.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/updater/network_fetcher.h"
#include "cobalt/updater/patcher.h"
#include "cobalt/updater/prefs.h"
#include "cobalt/updater/unzipper.h"
#include "cobalt/updater/updater_constants.h"
#include "cobalt/version.h"
#include "components/prefs/pref_service.h"
#include "components/update_client/network.h"
#include "components/update_client/patcher.h"
#include "components/update_client/protocol_handler.h"
#include "components/update_client/unzipper.h"
#include "starboard/common/system_property.h"
#include "starboard/system.h"
#include "url/gurl.h"
using starboard::kSystemPropertyMaxLength;
namespace {
// Default time constants.
const int kDelayOneMinute = 60;
const int kDelayOneHour = kDelayOneMinute * 60;
const char kDefaultUpdaterChannel[] = "prod";
const char kOmahaCobaltLTSNightlyAppID[] =
"{26CD2F67-091F-4680-A9A9-2229635B65A5}";
const char kOmahaCobaltTrunkAppID[] = "{A9557415-DDCD-4948-8113-C643EFCF710C}";
const char kOmahaCobaltAppID[] = "{6D4E53F3-CC64-4CB8-B6BD-AB0B8F300E1C}";
std::string GetDeviceProperty(SbSystemPropertyId id) {
char value[kSystemPropertyMaxLength];
bool result;
result = SbSystemGetProperty(id, value, kSystemPropertyMaxLength);
std::string prop;
if (result) {
prop = std::string(value);
}
return prop;
}
} // namespace
namespace cobalt {
namespace updater {
Configurator::Configurator(network::NetworkModule* network_module)
: pref_service_(CreatePrefService()),
persisted_data_(std::make_unique<update_client::PersistedData>(
pref_service_.get(), nullptr)),
is_channel_changed_(0),
unzip_factory_(base::MakeRefCounted<UnzipperFactory>()),
network_fetcher_factory_(
base::MakeRefCounted<NetworkFetcherFactoryCobalt>(network_module)),
patch_factory_(base::MakeRefCounted<PatcherFactory>()) {
LOG(INFO) << "Configurator::Configurator";
const std::string persisted_channel = persisted_data_->GetLatestChannel();
if (persisted_channel.empty()) {
SetChannel(kDefaultUpdaterChannel);
} else {
SetChannel(persisted_channel);
}
if (network_module != nullptr) {
user_agent_string_ = network_module->GetUserAgent();
}
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
browser::switches::kUseCompressedUpdates)) {
use_compressed_updates_.store(true);
} else {
use_compressed_updates_.store(false);
}
}
Configurator::~Configurator() { LOG(INFO) << "Configurator::~Configurator"; }
int Configurator::InitialDelay() const { return 0; }
int Configurator::NextCheckDelay() const { return 5 * kDelayOneHour; }
int Configurator::OnDemandDelay() const { return 0; }
int Configurator::UpdateDelay() const { return 0; }
std::vector<GURL> Configurator::UpdateUrl() const {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
browser::switches::kUseQAUpdateServer)) {
return std::vector<GURL>{GURL(kUpdaterJSONDefaultUrlQA)};
} else {
return std::vector<GURL>{GURL(kUpdaterJSONDefaultUrl)};
}
}
std::vector<GURL> Configurator::PingUrl() const { return UpdateUrl(); }
std::string Configurator::GetProdId() const { return "cobalt"; }
base::Version Configurator::GetBrowserVersion() const {
std::string version(COBALT_VERSION);
// base::Version only accepts numeric versions. Return Cobalt major version.
int first_dot = version.find_first_of(".");
if (first_dot != std::string::npos) {
return base::Version(version.substr(0, first_dot));
}
return base::Version("");
}
std::string Configurator::GetBrand() const { return {}; }
std::string Configurator::GetLang() const {
const char* locale_id = SbSystemGetLocaleId();
if (!locale_id) {
// If Starboard failed to determine the locale, return a hardcoded, but
// valid BCP 47 language tag as required by
// https://html.spec.whatwg.org/commit-snapshots/e2f08b4e56d9a098038fb16c7ff6bb820a57cfab/#language-preferences
return "en-US";
}
std::string locale_string(locale_id);
// POSIX platforms put time zone id at the end of the locale id, like
// |en_US.UTF8|. We remove the time zone id.
int first_dot = locale_string.find_first_of(".");
if (first_dot != std::string::npos) {
return locale_string.substr(0, first_dot);
}
return locale_string;
}
std::string Configurator::GetOSLongName() const {
return GetDeviceProperty(kSbSystemPropertyPlatformName);
}
base::flat_map<std::string, std::string> Configurator::ExtraRequestParams()
const {
base::flat_map<std::string, std::string> params;
params.insert(std::make_pair("SABI", SB_SABI_JSON_ID));
params.insert(std::make_pair("sbversion", std::to_string(SB_API_VERSION)));
params.insert(
std::make_pair("jsengine", script::GetJavaScriptEngineNameAndVersion()));
params.insert(std::make_pair(
"updaterchannelchanged",
SbAtomicNoBarrier_Load(&is_channel_changed_) == 1 ? "True" : "False"));
// Brand name
params.insert(
std::make_pair("brand", GetDeviceProperty(kSbSystemPropertyBrandName)));
// Model name
params.insert(
std::make_pair("model", GetDeviceProperty(kSbSystemPropertyModelName)));
// Original Design manufacturer name
params.insert(
std::make_pair("manufacturer",
GetDeviceProperty(kSbSystemPropertySystemIntegratorName)));
// Chipset model number
params.insert(std::make_pair(
"chipset", GetDeviceProperty(kSbSystemPropertyChipsetModelNumber)));
// Firmware version
params.insert(std::make_pair(
"firmware", GetDeviceProperty(kSbSystemPropertyFirmwareVersion)));
// Model year
params.insert(
std::make_pair("year", GetDeviceProperty(kSbSystemPropertyModelYear)));
// User Agent String
params.insert(std::make_pair("uastring", user_agent_string_));
// Certification scope
params.insert(std::make_pair(
"certscope", GetDeviceProperty(kSbSystemPropertyCertificationScope)));
// Compression status
params.insert(std::make_pair("usecompressedupdates",
GetUseCompressedUpdates() ? "True" : "False"));
return params;
}
std::string Configurator::GetDownloadPreference() const { return {}; }
scoped_refptr<update_client::NetworkFetcherFactory>
Configurator::GetNetworkFetcherFactory() {
return network_fetcher_factory_;
}
scoped_refptr<update_client::UnzipperFactory>
Configurator::GetUnzipperFactory() {
return unzip_factory_;
}
scoped_refptr<update_client::PatcherFactory> Configurator::GetPatcherFactory() {
return patch_factory_;
}
bool Configurator::EnabledDeltas() const { return false; }
bool Configurator::EnabledComponentUpdates() const { return false; }
bool Configurator::EnabledBackgroundDownloader() const { return false; }
// TODO: enable cup signing
bool Configurator::EnabledCupSigning() const { return false; }
PrefService* Configurator::GetPrefService() const {
return pref_service_.get();
}
update_client::ActivityDataService* Configurator::GetActivityDataService()
const {
return nullptr;
}
bool Configurator::IsPerUserInstall() const { return true; }
std::vector<uint8_t> Configurator::GetRunActionKeyHash() const { return {}; }
std::string Configurator::GetAppGuidHelper(const std::string& updater_channel,
const std::string& version) {
if (updater_channel == "ltsnightly") {
return kOmahaCobaltLTSNightlyAppID;
}
if (version.find(".lts.") != std::string::npos &&
version.find(".master.") == std::string::npos) {
return kOmahaCobaltAppID;
}
return kOmahaCobaltTrunkAppID;
}
std::string Configurator::GetAppGuid() const {
const std::string version(COBALT_VERSION);
return GetAppGuidHelper(updater_channel_, version);
}
std::unique_ptr<update_client::ProtocolHandlerFactory>
Configurator::GetProtocolHandlerFactory() const {
return std::make_unique<update_client::ProtocolHandlerFactoryJSON>();
}
update_client::RecoveryCRXElevator Configurator::GetRecoveryCRXElevator()
const {
return {};
}
void Configurator::CompareAndSwapChannelChanged(int old_value, int new_value) {
SbAtomicNoBarrier_CompareAndSwap(&is_channel_changed_, old_value, new_value);
}
// The updater channel is get and set by main web module thread and update
// client thread. The getter and set use a lock to prevent synchronization
// issue.
std::string Configurator::GetChannel() const {
base::AutoLock auto_lock(const_cast<base::Lock&>(updater_channel_lock_));
return updater_channel_;
}
void Configurator::SetChannel(const std::string& updater_channel) {
LOG(INFO) << "Configurator::SetChannel updater_channel=" << updater_channel;
base::AutoLock auto_lock(updater_channel_lock_);
updater_channel_ = updater_channel;
}
// The updater status is get by main web module thread and set by the updater
// thread. The getter and set use a lock to prevent synchronization issue.
std::string Configurator::GetUpdaterStatus() const {
base::AutoLock auto_lock(const_cast<base::Lock&>(updater_status_lock_));
return updater_status_;
}
void Configurator::SetUpdaterStatus(const std::string& status) {
base::AutoLock auto_lock(updater_status_lock_);
updater_status_ = status;
}
void Configurator::SetMinFreeSpaceBytes(uint64_t bytes) {
base::AutoLock auto_lock(const_cast<base::Lock&>(min_free_space_bytes_lock_));
min_free_space_bytes_ = bytes;
}
uint64_t Configurator::GetMinFreeSpaceBytes() {
base::AutoLock auto_lock(const_cast<base::Lock&>(min_free_space_bytes_lock_));
return min_free_space_bytes_;
}
std::string Configurator::GetPreviousUpdaterStatus() const {
base::AutoLock auto_lock(
const_cast<base::Lock&>(previous_updater_status_lock_));
return previous_updater_status_;
}
void Configurator::SetPreviousUpdaterStatus(const std::string& status) {
base::AutoLock auto_lock(previous_updater_status_lock_);
previous_updater_status_ = status;
}
bool Configurator::GetUseCompressedUpdates() const {
return use_compressed_updates_.load();
}
void Configurator::SetUseCompressedUpdates(bool use_compressed_updates) {
use_compressed_updates_.store(use_compressed_updates);
}
} // namespace updater
} // namespace cobalt