1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/sys_info.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/lazy_instance.h" 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_tokenizer.h" 133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <execinfo.h> 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char* kLinuxStandardBaseVersionKeys[] = { 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "CHROMEOS_RELEASE_VERSION", 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "GOOGLE_RELEASE", 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "DISTRIB_RELEASE", 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NULL 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char kLinuxStandardBaseReleaseFile[] = "/etc/lsb-release"; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstruct ChromeOSVersionNumbers { 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ChromeOSVersionNumbers() 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : major_version(0), 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen minor_version(0), 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bugfix_version(0), 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen parsed(false) { 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32 major_version; 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32 minor_version; 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32 bugfix_version; 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool parsed; 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic base::LazyInstance<ChromeOSVersionNumbers> 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen g_chrome_os_version_numbers(base::LINKER_INITIALIZED); 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SysInfo::OperatingSystemVersionNumbers(int32* major_version, 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32* minor_version, 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32* bugfix_version) { 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!g_chrome_os_version_numbers.Get().parsed) { 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The other implementations of SysInfo don't block on the disk. 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // See http://code.google.com/p/chromium/issues/detail?id=60394 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Perhaps the caller ought to cache this? 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Temporary allowing while we work the bug out. 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::ThreadRestrictions::ScopedAllowIO allow_io; 55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath path(kLinuxStandardBaseReleaseFile); 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string contents; 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (file_util::ReadFileToString(path, &contents)) { 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen g_chrome_os_version_numbers.Get().parsed = true; 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ParseLsbRelease(contents, 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &(g_chrome_os_version_numbers.Get().major_version), 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &(g_chrome_os_version_numbers.Get().minor_version), 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &(g_chrome_os_version_numbers.Get().bugfix_version)); 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *major_version = g_chrome_os_version_numbers.Get().major_version; 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *minor_version = g_chrome_os_version_numbers.Get().minor_version; 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *bugfix_version = g_chrome_os_version_numbers.Get().bugfix_version; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string SysInfo::GetLinuxStandardBaseVersionKey() { 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return std::string(kLinuxStandardBaseVersionKeys[0]); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SysInfo::ParseLsbRelease(const std::string& lsb_release, 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32* major_version, 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32* minor_version, 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32* bugfix_version) { 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t version_key_index = std::string::npos; 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; kLinuxStandardBaseVersionKeys[i] != NULL; ++i) { 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen version_key_index = lsb_release.find(kLinuxStandardBaseVersionKeys[i]); 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (std::string::npos != version_key_index) { 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (std::string::npos == version_key_index) { 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t start_index = lsb_release.find_first_of('=', version_key_index); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott start_index++; // Move past '='. 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t length = lsb_release.find_first_of('\n', start_index) - start_index; 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string version = lsb_release.substr(start_index, length); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StringTokenizer tokenizer(version, "."); 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(rkc): Ignore the 0. here; fix this once we move Chrome OS version 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // numbers from the 0.xx.yyy.zz format to the xx.yyy.zz format. 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Refer to http://code.google.com/p/chromium-os/issues/detail?id=15789 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (int i = 0; i < 4 && tokenizer.GetNext(); i++) { 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (1 == i) { 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch StringToInt(tokenizer.token_begin(), 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch tokenizer.token_end(), 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch major_version); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *minor_version = *bugfix_version = 0; 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (2 == i) { 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch StringToInt(tokenizer.token_begin(), 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch tokenizer.token_end(), 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch minor_version); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { // 3 == i 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch StringToInt(tokenizer.token_begin(), 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch tokenizer.token_end(), 113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bugfix_version); 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 119