File: version_loader.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 (161 lines) | stat: -rw-r--r-- 5,277 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/version/version_loader.h"

#include <stddef.h>

#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/i18n/time_formatting.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
#include "base/time/time.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"

namespace chromeos {
namespace version_loader {

namespace {

// Beginning of line we look for that gives full version number.
// Format: x.x.xx.x (Developer|Official build extra info) board info
const char kFullVersionKey[] = "CHROMEOS_RELEASE_DESCRIPTION";

// Same but for short version (x.x.xx.x).
const char kVersionKey[] = "CHROMEOS_RELEASE_VERSION";

// Same but for ARC version.
const char kArcVersionKey[] = "CHROMEOS_ARC_VERSION";

// Same but for ARC Android SDK Version
const char kArcAndroidSdkVersionKey[] = "CHROMEOS_ARC_ANDROID_SDK_VERSION";

// Beginning of line we look for that gives the firmware version.
const char kFirmwarePrefix[] = "version";

// File to look for firmware number in.
const char kPathFirmware[] = "/var/log/bios_info.txt";

}  // namespace

std::optional<std::string> GetVersion(VersionFormat format) {
  std::string version;
  std::string key = (format == VERSION_FULL ? kFullVersionKey : kVersionKey);
  if (!base::SysInfo::GetLsbReleaseValue(key, &version)) {
    LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
        << "No LSB version key: " << key;
    return std::nullopt;
  }
  if (format == VERSION_SHORT_WITH_DATE) {
    version += base::UnlocalizedTimeFormatWithPattern(
        base::SysInfo::GetLsbReleaseTime(), "-yy.MM.dd",
        icu::TimeZone::getGMT());
  }

  return version;
}

std::string GetArcVersion() {
  std::string version;
  if (!base::SysInfo::GetLsbReleaseValue(kArcVersionKey, &version)) {
    LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
        << "No LSB version key: " << kArcVersionKey;
  }
  return version;
}

std::optional<std::string> GetArcAndroidSdkVersion() {
  std::string arc_sdk_version;

  if (!base::SysInfo::GetLsbReleaseValue(kArcAndroidSdkVersionKey,
                                         &arc_sdk_version)) {
    LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
        << "No LSB version key: " << kArcAndroidSdkVersionKey;
    return std::nullopt;
  }

  return arc_sdk_version;
}

std::string GetFirmware() {
  std::string firmware;
  std::string contents;
  const base::FilePath file_path(kPathFirmware);
  if (base::ReadFileToString(file_path, &contents)) {
    firmware = ParseFirmware(contents);
  }
  return firmware;
}

std::string ParseFirmware(const std::string& contents) {
  // The file contains lines such as:
  // vendor           | ...
  // version          | ...
  // release_date     | ...
  // We don't make any assumption that the spaces between "version" and "|" is
  //   fixed. So we just match kFirmwarePrefix at the start of the line and find
  //   the first character that is not "|" or space

  std::string_view firmware_prefix(kFirmwarePrefix);
  for (const std::string& line : base::SplitString(
           contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
    if (base::StartsWith(line, firmware_prefix,
                         base::CompareCase::INSENSITIVE_ASCII)) {
      std::string str = line.substr(firmware_prefix.size());
      size_t found = str.find_first_not_of("| ");
      if (found != std::string::npos)
        return str.substr(found);
    }
  }
  return std::string();
}

bool IsRollback(const std::string& current_version,
                const std::string& new_version) {
  VLOG(1) << "Current version: " << current_version;
  VLOG(1) << "New version: " << new_version;

  if (new_version == "0.0.0.0") {
    // No update available.
    return false;
  }

  std::vector<std::string> current_version_parts = base::SplitString(
      current_version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  std::vector<std::string> new_version_parts = base::SplitString(
      new_version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);

  for (size_t i = 0;
       i < current_version_parts.size() && i < new_version_parts.size(); ++i) {
    if (current_version_parts[i] == new_version_parts[i])
      continue;

    unsigned int current_part, new_part;
    if (!base::StringToUint(current_version_parts[i], &current_part) ||
        !base::StringToUint(new_version_parts[i], &new_part)) {
      // One of the parts is not a number (e.g. date in test builds), compare
      // strings.
      return current_version_parts[i] > new_version_parts[i];
    }
    return current_part > new_part;
  }

  // Return true if new version is prefix of current version, false otherwise.
  return new_version_parts.size() < current_version_parts.size();
}

}  // namespace version_loader
}  // namespace chromeos