| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 | |
| 5 #include "base/sys_info.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/environment.h" | |
| 9 #include "base/files/file.h" | |
| 10 #include "base/files/file_path.h" | |
| 11 #include "base/files/file_util.h" | |
| 12 #include "base/lazy_instance.h" | |
| 13 #include "base/strings/string_number_conversions.h" | |
| 14 #include "base/strings/string_piece.h" | |
| 15 #include "base/strings/string_split.h" | |
| 16 #include "base/strings/string_tokenizer.h" | |
| 17 #include "base/strings/string_util.h" | |
| 18 #include "base/threading/thread_restrictions.h" | |
| 19 | |
| 20 namespace base { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 const char* const kLinuxStandardBaseVersionKeys[] = { | |
| 25 "CHROMEOS_RELEASE_VERSION", | |
| 26 "GOOGLE_RELEASE", | |
| 27 "DISTRIB_RELEASE", | |
| 28 }; | |
| 29 | |
| 30 const char kChromeOsReleaseNameKey[] = "CHROMEOS_RELEASE_NAME"; | |
| 31 | |
| 32 const char* const kChromeOsReleaseNames[] = { | |
| 33 "Chrome OS", | |
| 34 "Chromium OS", | |
| 35 }; | |
| 36 | |
| 37 const char kLinuxStandardBaseReleaseFile[] = "/etc/lsb-release"; | |
| 38 | |
| 39 const char kLsbReleaseKey[] = "LSB_RELEASE"; | |
| 40 const char kLsbReleaseTimeKey[] = "LSB_RELEASE_TIME"; // Seconds since epoch | |
| 41 | |
| 42 const char kLsbReleaseSourceKey[] = "lsb-release"; | |
| 43 const char kLsbReleaseSourceEnv[] = "env"; | |
| 44 const char kLsbReleaseSourceFile[] = "file"; | |
| 45 | |
| 46 class ChromeOSVersionInfo { | |
| 47 public: | |
| 48 ChromeOSVersionInfo() { | |
| 49 Parse(); | |
| 50 } | |
| 51 | |
| 52 void Parse() { | |
| 53 lsb_release_map_.clear(); | |
| 54 major_version_ = 0; | |
| 55 minor_version_ = 0; | |
| 56 bugfix_version_ = 0; | |
| 57 is_running_on_chromeos_ = false; | |
| 58 | |
| 59 std::string lsb_release, lsb_release_time_str; | |
| 60 scoped_ptr<Environment> env(Environment::Create()); | |
| 61 bool parsed_from_env = | |
| 62 env->GetVar(kLsbReleaseKey, &lsb_release) && | |
| 63 env->GetVar(kLsbReleaseTimeKey, &lsb_release_time_str); | |
| 64 if (parsed_from_env) { | |
| 65 double us = 0; | |
| 66 if (StringToDouble(lsb_release_time_str, &us)) | |
| 67 lsb_release_time_ = Time::FromDoubleT(us); | |
| 68 } else { | |
| 69 // If the LSB_RELEASE and LSB_RELEASE_TIME environment variables are not | |
| 70 // set, fall back to a blocking read of the lsb_release file. This should | |
| 71 // only happen in non Chrome OS environments. | |
| 72 ThreadRestrictions::ScopedAllowIO allow_io; | |
| 73 FilePath path(kLinuxStandardBaseReleaseFile); | |
| 74 ReadFileToString(path, &lsb_release); | |
| 75 File::Info fileinfo; | |
| 76 if (GetFileInfo(path, &fileinfo)) | |
| 77 lsb_release_time_ = fileinfo.creation_time; | |
| 78 } | |
| 79 ParseLsbRelease(lsb_release); | |
| 80 // For debugging: | |
| 81 lsb_release_map_[kLsbReleaseSourceKey] = | |
| 82 parsed_from_env ? kLsbReleaseSourceEnv : kLsbReleaseSourceFile; | |
| 83 } | |
| 84 | |
| 85 bool GetLsbReleaseValue(const std::string& key, std::string* value) { | |
| 86 SysInfo::LsbReleaseMap::const_iterator iter = lsb_release_map_.find(key); | |
| 87 if (iter == lsb_release_map_.end()) | |
| 88 return false; | |
| 89 *value = iter->second; | |
| 90 return true; | |
| 91 } | |
| 92 | |
| 93 void GetVersionNumbers(int32* major_version, | |
| 94 int32* minor_version, | |
| 95 int32* bugfix_version) { | |
| 96 *major_version = major_version_; | |
| 97 *minor_version = minor_version_; | |
| 98 *bugfix_version = bugfix_version_; | |
| 99 } | |
| 100 | |
| 101 const Time& lsb_release_time() const { return lsb_release_time_; } | |
| 102 const SysInfo::LsbReleaseMap& lsb_release_map() const { | |
| 103 return lsb_release_map_; | |
| 104 } | |
| 105 bool is_running_on_chromeos() const { return is_running_on_chromeos_; } | |
| 106 | |
| 107 private: | |
| 108 void ParseLsbRelease(const std::string& lsb_release) { | |
| 109 // Parse and cache lsb_release key pairs. There should only be a handful | |
| 110 // of entries so the overhead for this will be small, and it can be | |
| 111 // useful for debugging. | |
| 112 base::StringPairs pairs; | |
| 113 SplitStringIntoKeyValuePairs(lsb_release, '=', '\n', &pairs); | |
| 114 for (size_t i = 0; i < pairs.size(); ++i) { | |
| 115 std::string key, value; | |
| 116 TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key); | |
| 117 TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value); | |
| 118 if (key.empty()) | |
| 119 continue; | |
| 120 lsb_release_map_[key] = value; | |
| 121 } | |
| 122 // Parse the version from the first matching recognized version key. | |
| 123 std::string version; | |
| 124 for (size_t i = 0; i < arraysize(kLinuxStandardBaseVersionKeys); ++i) { | |
| 125 std::string key = kLinuxStandardBaseVersionKeys[i]; | |
| 126 if (GetLsbReleaseValue(key, &version) && !version.empty()) | |
| 127 break; | |
| 128 } | |
| 129 StringTokenizer tokenizer(version, "."); | |
| 130 if (tokenizer.GetNext()) { | |
| 131 StringToInt(StringPiece(tokenizer.token_begin(), tokenizer.token_end()), | |
| 132 &major_version_); | |
| 133 } | |
| 134 if (tokenizer.GetNext()) { | |
| 135 StringToInt(StringPiece(tokenizer.token_begin(), tokenizer.token_end()), | |
| 136 &minor_version_); | |
| 137 } | |
| 138 if (tokenizer.GetNext()) { | |
| 139 StringToInt(StringPiece(tokenizer.token_begin(), tokenizer.token_end()), | |
| 140 &bugfix_version_); | |
| 141 } | |
| 142 | |
| 143 // Check release name for Chrome OS. | |
| 144 std::string release_name; | |
| 145 if (GetLsbReleaseValue(kChromeOsReleaseNameKey, &release_name)) { | |
| 146 for (size_t i = 0; i < arraysize(kChromeOsReleaseNames); ++i) { | |
| 147 if (release_name == kChromeOsReleaseNames[i]) { | |
| 148 is_running_on_chromeos_ = true; | |
| 149 break; | |
| 150 } | |
| 151 } | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 Time lsb_release_time_; | |
| 156 SysInfo::LsbReleaseMap lsb_release_map_; | |
| 157 int32 major_version_; | |
| 158 int32 minor_version_; | |
| 159 int32 bugfix_version_; | |
| 160 bool is_running_on_chromeos_; | |
| 161 }; | |
| 162 | |
| 163 static LazyInstance<ChromeOSVersionInfo> | |
| 164 g_chrome_os_version_info = LAZY_INSTANCE_INITIALIZER; | |
| 165 | |
| 166 ChromeOSVersionInfo& GetChromeOSVersionInfo() { | |
| 167 return g_chrome_os_version_info.Get(); | |
| 168 } | |
| 169 | |
| 170 } // namespace | |
| 171 | |
| 172 // static | |
| 173 void SysInfo::OperatingSystemVersionNumbers(int32* major_version, | |
| 174 int32* minor_version, | |
| 175 int32* bugfix_version) { | |
| 176 return GetChromeOSVersionInfo().GetVersionNumbers( | |
| 177 major_version, minor_version, bugfix_version); | |
| 178 } | |
| 179 | |
| 180 // static | |
| 181 const SysInfo::LsbReleaseMap& SysInfo::GetLsbReleaseMap() { | |
| 182 return GetChromeOSVersionInfo().lsb_release_map(); | |
| 183 } | |
| 184 | |
| 185 // static | |
| 186 bool SysInfo::GetLsbReleaseValue(const std::string& key, std::string* value) { | |
| 187 return GetChromeOSVersionInfo().GetLsbReleaseValue(key, value); | |
| 188 } | |
| 189 | |
| 190 // static | |
| 191 std::string SysInfo::GetLsbReleaseBoard() { | |
| 192 const char kMachineInfoBoard[] = "CHROMEOS_RELEASE_BOARD"; | |
| 193 std::string board; | |
| 194 if (!GetLsbReleaseValue(kMachineInfoBoard, &board)) | |
| 195 board = "unknown"; | |
| 196 return board; | |
| 197 } | |
| 198 | |
| 199 // static | |
| 200 Time SysInfo::GetLsbReleaseTime() { | |
| 201 return GetChromeOSVersionInfo().lsb_release_time(); | |
| 202 } | |
| 203 | |
| 204 // static | |
| 205 bool SysInfo::IsRunningOnChromeOS() { | |
| 206 return GetChromeOSVersionInfo().is_running_on_chromeos(); | |
| 207 } | |
| 208 | |
| 209 // static | |
| 210 void SysInfo::SetChromeOSVersionInfoForTest(const std::string& lsb_release, | |
| 211 const Time& lsb_release_time) { | |
| 212 scoped_ptr<Environment> env(Environment::Create()); | |
| 213 env->SetVar(kLsbReleaseKey, lsb_release); | |
| 214 env->SetVar(kLsbReleaseTimeKey, | |
| 215 DoubleToString(lsb_release_time.ToDoubleT())); | |
| 216 g_chrome_os_version_info.Get().Parse(); | |
| 217 } | |
| 218 | |
| 219 } // namespace base | |
| OLD | NEW |