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.
5 #include "base/sys_info.h"
7 #include <sys/system_properties.h>
9 #include "base/android/sys_utils.h"
10 #include "base/lazy_instance.h"
11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_piece.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/sys_info_internal.h"
19 // Default version of Android to fall back to when actual version numbers
20 // cannot be acquired. Use the latest Android release with a higher bug fix
21 // version to avoid unnecessarily comparison errors with the latest release.
22 // This should be manually kept up-to-date on each Android release.
23 const int kDefaultAndroidMajorVersion
= 4;
24 const int kDefaultAndroidMinorVersion
= 4;
25 const int kDefaultAndroidBugfixVersion
= 99;
27 // Parse out the OS version numbers from the system properties.
28 void ParseOSVersionNumbers(const char* os_version_str
,
31 int32
*bugfix_version
) {
32 if (os_version_str
[0]) {
33 // Try to parse out the version numbers from the string.
34 int num_read
= sscanf(os_version_str
, "%d.%d.%d", major_version
,
35 minor_version
, bugfix_version
);
38 // If we don't have a full set of version numbers, make the extras 0.
39 if (num_read
< 2) *minor_version
= 0;
40 if (num_read
< 3) *bugfix_version
= 0;
45 // For some reason, we couldn't parse the version number string.
46 *major_version
= kDefaultAndroidMajorVersion
;
47 *minor_version
= kDefaultAndroidMinorVersion
;
48 *bugfix_version
= kDefaultAndroidBugfixVersion
;
51 // Parses a system property (specified with unit 'k','m' or 'g').
52 // Returns a value in bytes.
53 // Returns -1 if the string could not be parsed.
54 int64
ParseSystemPropertyBytes(const base::StringPiece
& str
) {
55 const int64 KB
= 1024;
56 const int64 MB
= 1024 * KB
;
57 const int64 GB
= 1024 * MB
;
60 int64 unit_multiplier
= 1;
61 size_t length
= str
.size();
62 if (str
[length
- 1] == 'k') {
65 } else if (str
[length
- 1] == 'm') {
68 } else if (str
[length
- 1] == 'g') {
73 bool parsed
= base::StringToInt64(str
.substr(0, length
), &result
);
74 bool negative
= result
<= 0;
75 bool overflow
= result
>= std::numeric_limits
<int64
>::max() / unit_multiplier
;
76 if (!parsed
|| negative
|| overflow
)
78 return result
* unit_multiplier
;
81 int GetDalvikHeapSizeMB() {
82 char heap_size_str
[PROP_VALUE_MAX
];
83 __system_property_get("dalvik.vm.heapsize", heap_size_str
);
84 // dalvik.vm.heapsize property is writable by a root user.
85 // Clamp it to reasonable range as a sanity check,
86 // a typical android device will never have less than 48MB.
87 const int64 MB
= 1024 * 1024;
88 int64 result
= ParseSystemPropertyBytes(heap_size_str
);
90 // We should consider not exposing these values if they are not reliable.
91 LOG(ERROR
) << "Can't parse dalvik.vm.heapsize: " << heap_size_str
;
92 result
= base::SysInfo::AmountOfPhysicalMemoryMB() / 3;
94 result
= std::min
<int64
>(std::max
<int64
>(32 * MB
, result
), 1024 * MB
) / MB
;
95 return static_cast<int>(result
);
98 int GetDalvikHeapGrowthLimitMB() {
99 char heap_size_str
[PROP_VALUE_MAX
];
100 __system_property_get("dalvik.vm.heapgrowthlimit", heap_size_str
);
101 // dalvik.vm.heapgrowthlimit property is writable by a root user.
102 // Clamp it to reasonable range as a sanity check,
103 // a typical android device will never have less than 24MB.
104 const int64 MB
= 1024 * 1024;
105 int64 result
= ParseSystemPropertyBytes(heap_size_str
);
107 // We should consider not exposing these values if they are not reliable.
108 LOG(ERROR
) << "Can't parse dalvik.vm.heapgrowthlimit: " << heap_size_str
;
109 result
= base::SysInfo::AmountOfPhysicalMemoryMB() / 6;
111 result
= std::min
<int64
>(std::max
<int64
>(16 * MB
, result
), 512 * MB
) / MB
;
112 return static_cast<int>(result
);
115 } // anonymous namespace
119 std::string
SysInfo::OperatingSystemName() {
123 std::string
SysInfo::GetAndroidBuildCodename() {
124 char os_version_codename_str
[PROP_VALUE_MAX
];
125 __system_property_get("ro.build.version.codename", os_version_codename_str
);
126 return std::string(os_version_codename_str
);
129 std::string
SysInfo::GetAndroidBuildID() {
130 char os_build_id_str
[PROP_VALUE_MAX
];
131 __system_property_get("ro.build.id", os_build_id_str
);
132 return std::string(os_build_id_str
);
135 std::string
SysInfo::GetDeviceName() {
136 char device_model_str
[PROP_VALUE_MAX
];
137 __system_property_get("ro.product.model", device_model_str
);
138 return std::string(device_model_str
);
141 std::string
SysInfo::OperatingSystemVersion() {
142 int32 major
, minor
, bugfix
;
143 OperatingSystemVersionNumbers(&major
, &minor
, &bugfix
);
144 return StringPrintf("%d.%d.%d", major
, minor
, bugfix
);
147 void SysInfo::OperatingSystemVersionNumbers(int32
* major_version
,
148 int32
* minor_version
,
149 int32
* bugfix_version
) {
150 // Read the version number string out from the properties.
151 char os_version_str
[PROP_VALUE_MAX
];
152 __system_property_get("ro.build.version.release", os_version_str
);
154 // Parse out the numbers.
155 ParseOSVersionNumbers(os_version_str
, major_version
, minor_version
,
159 int SysInfo::DalvikHeapSizeMB() {
160 static int heap_size
= GetDalvikHeapSizeMB();
164 int SysInfo::DalvikHeapGrowthLimitMB() {
165 static int heap_growth_limit
= GetDalvikHeapGrowthLimitMB();
166 return heap_growth_limit
;
169 static base::LazyInstance
<
170 base::internal::LazySysInfoValue
<bool,
171 android::SysUtils::IsLowEndDeviceFromJni
> >::Leaky
172 g_lazy_low_end_device
= LAZY_INSTANCE_INITIALIZER
;
174 bool SysInfo::IsLowEndDevice() {
175 return g_lazy_low_end_device
.Get().value();