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/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/stringprintf.h"
16 // Default version of Android to fall back to when actual version numbers
17 // cannot be acquired.
18 // TODO(dfalcantara): Keep this reasonably up to date with the latest publicly
19 // available version of Android.
20 const int kDefaultAndroidMajorVersion
= 4;
21 const int kDefaultAndroidMinorVersion
= 3;
22 const int kDefaultAndroidBugfixVersion
= 0;
24 // Parse out the OS version numbers from the system properties.
25 void ParseOSVersionNumbers(const char* os_version_str
,
28 int32
*bugfix_version
) {
29 if (os_version_str
[0]) {
30 // Try to parse out the version numbers from the string.
31 int num_read
= sscanf(os_version_str
, "%d.%d.%d", major_version
,
32 minor_version
, bugfix_version
);
35 // If we don't have a full set of version numbers, make the extras 0.
36 if (num_read
< 2) *minor_version
= 0;
37 if (num_read
< 3) *bugfix_version
= 0;
42 // For some reason, we couldn't parse the version number string.
43 *major_version
= kDefaultAndroidMajorVersion
;
44 *minor_version
= kDefaultAndroidMinorVersion
;
45 *bugfix_version
= kDefaultAndroidBugfixVersion
;
48 // Parses a system property (specified with unit 'k','m' or 'g').
49 // Returns a value in bytes.
50 // Returns -1 if the string could not be parsed.
51 int64
ParseSystemPropertyBytes(const base::StringPiece
& str
) {
52 const int64 KB
= 1024;
53 const int64 MB
= 1024 * KB
;
54 const int64 GB
= 1024 * MB
;
57 int64 unit_multiplier
= 1;
58 size_t length
= str
.size();
59 if (str
[length
- 1] == 'k') {
62 } else if (str
[length
- 1] == 'm') {
65 } else if (str
[length
- 1] == 'g') {
70 bool parsed
= base::StringToInt64(str
.substr(0, length
), &result
);
71 bool negative
= result
<= 0;
72 bool overflow
= result
>= std::numeric_limits
<int64
>::max() / unit_multiplier
;
73 if (!parsed
|| negative
|| overflow
)
75 return result
* unit_multiplier
;
78 int GetDalvikHeapSizeMB() {
79 char heap_size_str
[PROP_VALUE_MAX
];
80 __system_property_get("dalvik.vm.heapsize", heap_size_str
);
81 // dalvik.vm.heapsize property is writable by a root user.
82 // Clamp it to reasonable range as a sanity check,
83 // a typical android device will never have less than 48MB.
84 const int64 MB
= 1024 * 1024;
85 int64 result
= ParseSystemPropertyBytes(heap_size_str
);
87 // We should consider not exposing these values if they are not reliable.
88 LOG(ERROR
) << "Can't parse dalvik.vm.heapsize: " << heap_size_str
;
89 result
= base::SysInfo::AmountOfPhysicalMemoryMB() / 3;
91 result
= std::min
<int64
>(std::max
<int64
>(32 * MB
, result
), 1024 * MB
) / MB
;
92 return static_cast<int>(result
);
95 int GetDalvikHeapGrowthLimitMB() {
96 char heap_size_str
[PROP_VALUE_MAX
];
97 __system_property_get("dalvik.vm.heapgrowthlimit", heap_size_str
);
98 // dalvik.vm.heapgrowthlimit property is writable by a root user.
99 // Clamp it to reasonable range as a sanity check,
100 // a typical android device will never have less than 24MB.
101 const int64 MB
= 1024 * 1024;
102 int64 result
= ParseSystemPropertyBytes(heap_size_str
);
104 // We should consider not exposing these values if they are not reliable.
105 LOG(ERROR
) << "Can't parse dalvik.vm.heapgrowthlimit: " << heap_size_str
;
106 result
= base::SysInfo::AmountOfPhysicalMemoryMB() / 6;
108 result
= std::min
<int64
>(std::max
<int64
>(16 * MB
, result
), 512 * MB
) / MB
;
109 return static_cast<int>(result
);
112 } // anonymous namespace
116 std::string
SysInfo::OperatingSystemName() {
120 std::string
SysInfo::GetAndroidBuildCodename() {
121 char os_version_codename_str
[PROP_VALUE_MAX
];
122 __system_property_get("ro.build.version.codename", os_version_codename_str
);
123 return std::string(os_version_codename_str
);
126 std::string
SysInfo::GetAndroidBuildID() {
127 char os_build_id_str
[PROP_VALUE_MAX
];
128 __system_property_get("ro.build.id", os_build_id_str
);
129 return std::string(os_build_id_str
);
132 std::string
SysInfo::GetDeviceName() {
133 char device_model_str
[PROP_VALUE_MAX
];
134 __system_property_get("ro.product.model", device_model_str
);
135 return std::string(device_model_str
);
138 std::string
SysInfo::OperatingSystemVersion() {
139 int32 major
, minor
, bugfix
;
140 OperatingSystemVersionNumbers(&major
, &minor
, &bugfix
);
141 return StringPrintf("%d.%d.%d", major
, minor
, bugfix
);
144 void SysInfo::OperatingSystemVersionNumbers(int32
* major_version
,
145 int32
* minor_version
,
146 int32
* bugfix_version
) {
147 // Read the version number string out from the properties.
148 char os_version_str
[PROP_VALUE_MAX
];
149 __system_property_get("ro.build.version.release", os_version_str
);
151 // Parse out the numbers.
152 ParseOSVersionNumbers(os_version_str
, major_version
, minor_version
,
156 int SysInfo::DalvikHeapSizeMB() {
157 static int heap_size
= GetDalvikHeapSizeMB();
161 int SysInfo::DalvikHeapGrowthLimitMB() {
162 static int heap_growth_limit
= GetDalvikHeapGrowthLimitMB();
163 return heap_growth_limit
;