1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
#filter substitution
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import android.os.StrictMode;
import android.util.Log;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A collection of system info values, broadly mirroring a subset of
* nsSystemInfo. See also the constants in AppConstants, which reflect
* much of nsIXULAppInfo.
*/
public final class SysInfo {
private static final String LOG_TAG = "GeckoSysInfo";
// We don't mind an instant of possible duplicate work, we only wish to
// avoid inconsistency, so we don't bother with synchronization for
// these.
private static volatile int cpuCount = -1;
private static volatile int totalRAM = -1;
/**
* Get the number of cores on the device.
*
* We can't use a nice tidy API call, because they're all wrong:
*
* <http://stackoverflow.com/questions/7962155/how-can-you-detect-a-dual-core-
* cpu-on-an-android-device-from-code>
*
* This method is based on that code.
*
* @return the number of CPU cores, or 1 if the number could not be
* determined.
*/
public static int getCPUCount() {
if (cpuCount > 0) {
return cpuCount;
}
if (android.os.Build.VERSION.SDK_INT < 9) {
return readCPUCount();
}
// Avoid a strict mode warning... but only on devices that have StrictMode.
StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
try {
return readCPUCount();
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
private static int readCPUCount() {
class CpuFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
return Pattern.matches("cpu[0-9]+", pathname.getName());
}
}
try {
final File dir = new File("/sys/devices/system/cpu/");
return cpuCount = dir.listFiles(new CpuFilter()).length;
} catch (Exception e) {
Log.w(LOG_TAG, "Assuming 1 CPU; got exception.", e);
return cpuCount = 1;
}
}
/**
* Fetch the total memory of the device in MB by parsing /proc/meminfo.
*
* Of course, Android doesn't have a neat and tidy way to find total
* RAM, so we do it by parsing /proc/meminfo.
*
* @return 0 if a problem occurred, or memory size in MB.
*/
public static int getMemSize() {
if (totalRAM >= 0) {
return totalRAM;
}
try {
RandomAccessFile reader = new RandomAccessFile("/proc/meminfo", "r");
try {
// MemTotal will be one of the first three lines.
int i = 0;
String memTotal = null;
while (i++ < 3) {
memTotal = reader.readLine();
if (memTotal == null ||
memTotal.startsWith("MemTotal: ")) {
break;
}
memTotal = null;
}
if (memTotal == null) {
return totalRAM = 0;
}
// Parse a line like this:
// MemTotal: 1605324 kB
Matcher m = Pattern.compile("^MemTotal:\\s+([0-9]+) kB\\s*$")
.matcher(memTotal);
if (m.matches()) {
String kb = m.group(1);
if (kb != null) {
return totalRAM = (Integer.parseInt(kb) / 1024);
}
}
Log.w(LOG_TAG, "Got unexpected MemTotal line: " + memTotal);
return totalRAM = 0;
} finally {
reader.close();
}
} catch (FileNotFoundException f) {
return totalRAM = 0;
} catch (IOException e) {
return totalRAM = 0;
}
}
/**
* @return the SDK version supported by this device, such as '16'.
*/
public static int getVersion() {
return android.os.Build.VERSION.SDK_INT;
}
/**
* @return the release version string, such as "4.1.2".
*/
public static String getReleaseVersion() {
return android.os.Build.VERSION.RELEASE;
}
/**
* @return the device manufacturer, such as "HTC".
*/
public static String getManufacturer() {
return android.os.Build.MANUFACTURER;
}
/**
* @return the device name, such as "HTC One".
*/
public static String getDevice() {
// No, not android.os.Build.DEVICE.
return android.os.Build.MODEL;
}
/**
* @return the Android "hardware" identifier, such as "m7".
*/
public static String getHardware() {
return android.os.Build.HARDWARE;
}
/**
* @return the system OS name. Hardcoded to "Android".
*/
public static String getName() {
// We deliberately differ from PR_SI_SYSNAME, which is "Linux".
return "Android";
}
/**
* @return the architecture string, excluding ABI.
*/
public static String getArch() {
return "@CPU_ARCH@"; // "arm"
}
/**
* @return the Android architecture string, including ABI.
*/
public static String getArchABI() {
// Android likes to include the ABI, too ("armeabiv7"), so we
// differ to add value.
return android.os.Build.CPU_ABI;
}
}
|