blob: 5baad0aa4a737887ae8ae24268421093c0ace232 [file] [log] [blame]
// Copyright 2021 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/utils.h"
#include <vector>
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/values.h"
#include "build/build_config.h"
#include "cobalt/extension/installation_manager.h"
#include "components/update_client/utils.h"
#include "starboard/configuration_constants.h"
#include "starboard/string.h"
#include "starboard/system.h"
#define PRODUCT_FULLNAME_STRING "cobalt_updater"
namespace cobalt {
namespace updater {
namespace {
// The default manifest version to assume when the actual manifest cannot be
// parsed for any reason. This should not be used for installation manager
// errors, or any other error unrelated to parsing the manifest.
const char kDefaultManifestVersion[] = "1.0.0";
} // namespace
bool CreateProductDirectory(base::FilePath* path) {
if (!GetProductDirectoryPath(path)) {
LOG(ERROR) << "Can't get product directory path";
return false;
}
if (!base::CreateDirectory(*path)) {
LOG(ERROR) << "Can't create product directory.";
return false;
}
return true;
}
bool GetProductDirectoryPath(base::FilePath* path) {
#if defined(OS_WIN)
constexpr int kPathKey = base::DIR_LOCAL_APP_DATA;
#elif defined(OS_MACOSX)
constexpr int kPathKey = base::DIR_APP_DATA;
#endif
#if !defined(STARBOARD)
base::FilePath app_data_dir;
if (!base::PathService::Get(kPathKey, &app_data_dir)) {
LOG(ERROR) << "Can't retrieve local app data directory.";
return false;
}
#endif
std::vector<char> storage_dir(kSbFileMaxPath);
#if SB_API_VERSION >= 12
if (!SbSystemGetPath(kSbSystemPathStorageDirectory, storage_dir.data(),
kSbFileMaxPath)) {
SB_LOG(ERROR) << "GetProductDirectoryPath: Failed to get "
"kSbSystemPathStorageDirectory";
return false;
}
#else
SB_NOTREACHED() << "GetProductDirectoryPath: kSbSystemPathStorageDirectory "
"is not available before "
"starboard version 12";
return false;
#endif
base::FilePath app_data_dir(storage_dir.data());
const auto product_data_dir =
app_data_dir.AppendASCII(PRODUCT_FULLNAME_STRING);
*path = product_data_dir;
return true;
}
base::Version ReadEvergreenVersion(base::FilePath installation_dir) {
auto manifest = update_client::ReadManifest(installation_dir);
if (!manifest) {
return base::Version();
}
auto version = manifest->FindKey("version");
if (version) {
return base::Version(version->GetString());
}
return base::Version();
}
const std::string GetLoadedInstallationEvergreenVersion() {
std::vector<char> system_path_content_dir(kSbFileMaxPath);
if (!SbSystemGetPath(kSbSystemPathContentDirectory,
system_path_content_dir.data(), kSbFileMaxPath)) {
SB_LOG(ERROR) << "Failed to get system path content directory";
return "";
}
// Get the parent directory of the system_path_content_dir, and read the
// manifest.json there
base::Version version = ReadEvergreenVersion(
base::FilePath(std::string(system_path_content_dir.begin(),
system_path_content_dir.end()))
.DirName());
if (!version.IsValid()) {
SB_LOG(ERROR) << "Failed to get the Evergreen version. Defaulting to "
<< kDefaultManifestVersion << ".";
return std::string(kDefaultManifestVersion);
}
return version.GetString();
}
const std::string GetCurrentEvergreenVersion() {
auto installation_manager =
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_manager) {
SB_LOG(ERROR) << "Failed to get installation manager extension, getting "
"the Evergreen version of the loaded installation.";
return GetLoadedInstallationEvergreenVersion();
}
// Get the update version from the manifest file under the current
// installation path.
int index = installation_manager->GetCurrentInstallationIndex();
if (index == IM_EXT_ERROR) {
SB_LOG(ERROR) << "Failed to get current installation index, getting the "
"Evergreen version of the currently loaded installation.";
return GetLoadedInstallationEvergreenVersion();
}
std::vector<char> installation_path(kSbFileMaxPath);
if (installation_manager->GetInstallationPath(
index, installation_path.data(), kSbFileMaxPath) == IM_EXT_ERROR) {
SB_LOG(ERROR) << "Failed to get installation path, getting the Evergreen "
"version of the currently loaded installation.";
return GetLoadedInstallationEvergreenVersion();
}
base::Version version = ReadEvergreenVersion(base::FilePath(
std::string(installation_path.begin(), installation_path.end())));
if (!version.IsValid()) {
SB_LOG(ERROR) << "Failed to get the Evergreen version. Defaulting to "
<< kDefaultManifestVersion << ".";
return std::string(kDefaultManifestVersion);
}
return version.GetString();
}
} // namespace updater
} // namespace cobalt