1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// 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 "chrome/browser/ash/borealis/borealis_hardware_checker.h"
#include "ash/constants/ash_features.h"
#include "base/cpu.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "chromeos/ash/components/system/statistics_provider.h"
#include "third_party/re2/src/re2/re2.h"
namespace borealis {
namespace {
constexpr uint64_t kGibi = 1024ull * 1024 * 1024;
// Regex used for CPU checks on intel processors, this means "any i{3,5,7}
// processor". e.g.:
// - Valid: 11th Gen Intel(R) Core(TM) i5-1145G7 @ 2.60GHz
// - Valid: Intel(R) Core(TM) 5 ...
// - Invalid: Intel(R) Pentium(R) Gold 7505
constexpr char kIntelCpuRegex[] = "((i[357]-)|(Core.* [357]))";
// As above, for AMD processors, e.g. "AMD Ryzen 3 5125C with Radeon Graphics".
constexpr char kAmdCpuRegex[] = "Ryzen [357]";
std::string* g_cpu_brand_for_test_ = nullptr;
// Returns the Board's name according to /etc/lsb-release. Strips any variant
// except the "-borealis" variant.
//
// Note: the comment on GetLsbReleaseBoard() (rightly) points out that we're
// not supposed to use LsbReleaseBoard directly, but rather set a flag in
// the overlay. We are not doing that as the following check is only a
// temporary hack necessary while we release borealis, but will be removed
// shortly afterwards. This check can fail in either direction and we won't
// be too upset.
std::string GetBoardName() {
// In a developer build, the name "volteer" or "volteer-borealis" will become
// "volteer-signed-mp-blahblah" and "volteer-borealis-signed..." on a signed
// build, so we want to stop everything after the "-" unless its "-borealis".
//
// This means a variant like "volteer-kernelnext" will be treated as "volteer"
// by us.
std::vector<std::string> pieces =
base::SplitString(base::SysInfo::GetLsbReleaseBoard(), "-",
base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
if (pieces.size() >= 2 && pieces[1] == "borealis") {
return pieces[0] + "-" + pieces[1];
}
DCHECK(!pieces.empty());
return pieces[0];
}
bool IsBoard(const std::string& board) {
return GetBoardName() == board;
}
bool BoardIn(const base::flat_set<std::string>& boards) {
return boards.contains(GetBoardName());
}
bool CpuRegexMatches(const std::string& cpu_regex) {
return RE2::PartialMatch(
g_cpu_brand_for_test_ ? *g_cpu_brand_for_test_
: base::CPU::GetInstanceNoAllocation().cpu_brand(),
cpu_regex);
}
bool HasMemory(uint64_t mem_bytes) {
return base::SysInfo::AmountOfPhysicalMemory() >= mem_bytes;
}
bool HasSufficientHardware(const std::string& cpu_regex) {
return HasMemory(7 * kGibi) && CpuRegexMatches(cpu_regex);
}
bool InTargetSegment() {
return base::FeatureList::IsEnabled(
ash::features::kFeatureManagementBorealis);
}
bool Check() {
if (BoardIn({"hatch", "drallion", "puff"})) {
return HasSufficientHardware(kIntelCpuRegex);
}
if (IsBoard("volteer")) {
return HasSufficientHardware(kIntelCpuRegex);
}
if (BoardIn({"brya", "adlrvp", "brask", "brox"})) {
return HasSufficientHardware(kIntelCpuRegex);
}
if (BoardIn({"guybrush", "majolica"})) {
return HasSufficientHardware(kAmdCpuRegex);
}
if (BoardIn({"aurora", "myst"})) {
return true;
}
if (IsBoard("nissa")) {
return HasSufficientHardware(kIntelCpuRegex) && InTargetSegment();
}
if (IsBoard("skyrim")) {
return HasSufficientHardware(kAmdCpuRegex) && InTargetSegment();
}
if (IsBoard("rex")) {
// TODO(307825451): .* allows any CPU, add the correct cpu regex once we
// know what that is.
return HasSufficientHardware(".*");
}
return false;
}
} // namespace
void HasSufficientHardware(base::OnceCallback<void(bool)> callback) {
ash::system::StatisticsProvider::GetInstance()
->ScheduleOnMachineStatisticsLoaded(base::BindOnce(
[](base::OnceCallback<void(bool)> callback) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, base::MayBlock(), base::BindOnce(&Check),
std::move(callback));
},
std::move(callback)));
}
void SetCpuForTesting(std::string* cpu_brand) {
g_cpu_brand_for_test_ = cpu_brand;
}
} // namespace borealis
|