File: borealis_hardware_checker.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (138 lines) | stat: -rw-r--r-- 4,566 bytes parent folder | download | duplicates (6)
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