version_loader.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chromeos/version/version_loader.h"
  5. #include <stddef.h>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/files/file_path.h"
  10. #include "base/files/file_util.h"
  11. #include "base/location.h"
  12. #include "base/logging.h"
  13. #include "base/strings/string_number_conversions.h"
  14. #include "base/strings/string_split.h"
  15. #include "base/strings/string_util.h"
  16. #include "base/strings/stringprintf.h"
  17. #include "base/strings/utf_string_conversions.h"
  18. #include "base/system/sys_info.h"
  19. #include "base/time/time.h"
  20. #include "chromeos/strings/grit/chromeos_strings.h"
  21. namespace chromeos {
  22. namespace version_loader {
  23. namespace {
  24. // Beginning of line we look for that gives full version number.
  25. // Format: x.x.xx.x (Developer|Official build extra info) board info
  26. const char kFullVersionKey[] = "CHROMEOS_RELEASE_DESCRIPTION";
  27. // Same but for short version (x.x.xx.x).
  28. const char kVersionKey[] = "CHROMEOS_RELEASE_VERSION";
  29. // Same but for ARC version.
  30. const char kArcVersionKey[] = "CHROMEOS_ARC_VERSION";
  31. // Same but for ARC Android SDK Version
  32. const char kArcAndroidSdkVersionKey[] = "CHROMEOS_ARC_ANDROID_SDK_VERSION";
  33. // Beginning of line we look for that gives the firmware version.
  34. const char kFirmwarePrefix[] = "version";
  35. // File to look for firmware number in.
  36. const char kPathFirmware[] = "/var/log/bios_info.txt";
  37. } // namespace
  38. std::string GetVersion(VersionFormat format) {
  39. std::string version;
  40. std::string key = (format == VERSION_FULL ? kFullVersionKey : kVersionKey);
  41. if (!base::SysInfo::GetLsbReleaseValue(key, &version)) {
  42. LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
  43. << "No LSB version key: " << key;
  44. version = "0.0.0.0";
  45. }
  46. if (format == VERSION_SHORT_WITH_DATE) {
  47. base::Time::Exploded ctime;
  48. base::SysInfo::GetLsbReleaseTime().UTCExplode(&ctime);
  49. version += base::StringPrintf("-%02u.%02u.%02u", ctime.year % 100,
  50. ctime.month, ctime.day_of_month);
  51. }
  52. return version;
  53. }
  54. std::string GetArcVersion() {
  55. std::string version;
  56. if (!base::SysInfo::GetLsbReleaseValue(kArcVersionKey, &version)) {
  57. LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
  58. << "No LSB version key: " << kArcVersionKey;
  59. }
  60. return version;
  61. }
  62. absl::optional<std::string> GetArcAndroidSdkVersion() {
  63. std::string arc_sdk_version;
  64. if (!base::SysInfo::GetLsbReleaseValue(kArcAndroidSdkVersionKey,
  65. &arc_sdk_version)) {
  66. LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
  67. << "No LSB version key: " << kArcAndroidSdkVersionKey;
  68. return absl::nullopt;
  69. }
  70. return arc_sdk_version;
  71. }
  72. std::string GetFirmware() {
  73. std::string firmware;
  74. std::string contents;
  75. const base::FilePath file_path(kPathFirmware);
  76. if (base::ReadFileToString(file_path, &contents)) {
  77. firmware = ParseFirmware(contents);
  78. }
  79. return firmware;
  80. }
  81. std::string ParseFirmware(const std::string& contents) {
  82. // The file contains lines such as:
  83. // vendor | ...
  84. // version | ...
  85. // release_date | ...
  86. // We don't make any assumption that the spaces between "version" and "|" is
  87. // fixed. So we just match kFirmwarePrefix at the start of the line and find
  88. // the first character that is not "|" or space
  89. base::StringPiece firmware_prefix(kFirmwarePrefix);
  90. for (const std::string& line : base::SplitString(
  91. contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
  92. if (base::StartsWith(line, firmware_prefix,
  93. base::CompareCase::INSENSITIVE_ASCII)) {
  94. std::string str = line.substr(firmware_prefix.size());
  95. size_t found = str.find_first_not_of("| ");
  96. if (found != std::string::npos)
  97. return str.substr(found);
  98. }
  99. }
  100. return std::string();
  101. }
  102. bool IsRollback(const std::string& current_version,
  103. const std::string& new_version) {
  104. VLOG(1) << "Current version: " << current_version;
  105. VLOG(1) << "New version: " << new_version;
  106. if (new_version == "0.0.0.0") {
  107. // No update available.
  108. return false;
  109. }
  110. std::vector<std::string> current_version_parts = base::SplitString(
  111. current_version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  112. std::vector<std::string> new_version_parts = base::SplitString(
  113. new_version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  114. for (size_t i = 0;
  115. i < current_version_parts.size() && i < new_version_parts.size(); ++i) {
  116. if (current_version_parts[i] == new_version_parts[i])
  117. continue;
  118. unsigned int current_part, new_part;
  119. if (!base::StringToUint(current_version_parts[i], &current_part) ||
  120. !base::StringToUint(new_version_parts[i], &new_part)) {
  121. // One of the parts is not a number (e.g. date in test builds), compare
  122. // strings.
  123. return current_version_parts[i] > new_version_parts[i];
  124. }
  125. return current_part > new_part;
  126. }
  127. // Return true if new version is prefix of current version, false otherwise.
  128. return new_version_parts.size() < current_version_parts.size();
  129. }
  130. } // namespace version_loader
  131. } // namespace chromeos