/****************************************************************************
**
** Copyright (C) 2010-2013 UC Mobile Ltd. All Rights Reserved
** File : SystemInfo.java
**
** Description : Get system information such as memory, cpu, gpu, etc...
**
** Creation : 2013/05/07
** Author : Roger (yixx@ucweb.com)
** History :
** Creation, 2013/05/07, Roger, Create the file
**
****************************************************************************/
package com.uc.webkit.utils;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.regex.Pattern;
import com.uc.webkit.helper.DisplayHelper;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.opengl.GLES10;
import android.os.Debug;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
public final class SystemInfo {
private static final boolean DEBUG = false;
private static final String TAG = "sys";
private static ActivityManager sManager = null;
private static Display sDisplay = null;
private static ActivityManager.MemoryInfo sMemInfo;
private static Debug.MemoryInfo sProcMemInfo;
private static float sDisplayRefreshRate = 60.0f;
private static long sTotalSize = 0;
private static long sFreeSize = 0;
private static long sCachedSize = 0;
private static int sCpuCores = 0;
private static int sCpuMaxFreq = 0;
private static final DisplayMetrics sDisplayMetrics = new DisplayMetrics();
private static final DisplayMetrics sDisplayRealMetrics = new DisplayMetrics();
private static int sScreenLayout = 0;
private static boolean matchText(byte[] buffer, int index, String text) {
int N = text.length();
if ((index+N) >= buffer.length) {
return false;
}
for (int i=0; i<N; i++) {
if (buffer[index+i] != text.charAt(i)) {
return false;
}
}
return true;
}
private static long extractMemValue(byte[] buffer, int index) {
while (index < buffer.length && buffer[index] != '\n') {
if (buffer[index] >= '0' && buffer[index] <= '9') {
int start = index;
index++;
while (index < buffer.length && buffer[index] >= '0'
&& buffer[index] <= '9') {
index++;
}
String str = new String(buffer, 0, start, index-start);
return ((long)Integer.parseInt(str)) * 1024;
}
index++;
}
return 0;
}
private static void readMemInfo() {
// Permit disk reads here, as /proc/meminfo isn't really "on
// disk" and should be fast. TODO: make BlockGuard ignore
// /proc/ and /sys/ files perhaps?
//StrictMode appear until 2.3, so do not used in here
//StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
try {
final byte[] buffer = new byte[1024];
sTotalSize = 0;
sFreeSize = 0;
sCachedSize = 0;
FileInputStream is = new FileInputStream("/proc/meminfo");
int len = is.read(buffer);
is.close();
final int BUFLEN = buffer.length;
int count = 0;
for (int i=0; i<len && count < 3; i++) {
if (matchText(buffer, i, "MemTotal")) {
i += 8;
sTotalSize = extractMemValue(buffer, i);
count++;
} else if (matchText(buffer, i, "MemFree")) {
i += 7;
sFreeSize = extractMemValue(buffer, i);
count++;
} else if (matchText(buffer, i, "Cached")) {
i += 6;
sCachedSize = extractMemValue(buffer, i);
count++;
}
while (i < BUFLEN && buffer[i] != '\n') {
i++;
}
}
} catch (java.io.FileNotFoundException e) {
} catch (java.io.IOException e) {
} finally {
//StrictMode.setThreadPolicy(savedPolicy);
}
}
public static void setup(Context context) {
sManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
sDisplay = wm.getDefaultDisplay();
sDisplayRefreshRate = sDisplay.getRefreshRate();
sDisplay.getMetrics(sDisplayMetrics);
DisplayHelper.getRealMetrics(sDisplay, sDisplayRealMetrics);
sScreenLayout = context.getResources().getConfiguration().screenLayout;
}
/**
* Memory Information
*/
public static long getMemTotalSize() {
if (sTotalSize == 0)
readMemInfo();
return sTotalSize;
}
public static int getMemTotalSizeMb() {
final long total = getMemTotalSize();
final long mb = 1024 * 1024;
return (int) (total / mb);
}
public static long getMemFreeSize() {
readMemInfo();
return sFreeSize;
}
public static long getMemCachedSize() {
readMemInfo();
return sCachedSize;
}
public static long getMemAvailableSize() {
getActivityMemoryInfo();
return sMemInfo.availMem;
}
public static Debug.MemoryInfo getProcessMemoryInfo() {
if (sProcMemInfo == null)
sProcMemInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(sProcMemInfo);
return sProcMemInfo;
}
public static ActivityManager.MemoryInfo getActivityMemoryInfo() {
if (sMemInfo == null) {
sMemInfo = new ActivityManager.MemoryInfo();
}
sManager.getMemoryInfo(sMemInfo);
return sMemInfo;
}
/**
* CPU Information
*/
/**
* Gets the number of cores available in this device, across all processors.
* Requires: Ability to peruse the filesystem at "/sys/devices/system/cpu"
* @return The number of cores, or 1 if failed to get result
*/
public static int getCpuCoresNum() {
//Private Class to display only CPU devices in the directory listing
class CpuFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
//Check if filename is "cpu", followed by a single digit number
if(Pattern.matches("cpu[0-9]", pathname.getName())) {
return true;
}
return false;
}
}
if (sCpuCores > 0)
return sCpuCores;
try {
//Get directory containing CPU info
File dir = new File("/sys/devices/system/cpu/");
//Filter to only list the devices we care about
File[] files = dir.listFiles(new CpuFilter());
if (DEBUG) Log.d(TAG, "CPU Count: "+files.length);
//Return the number of cores (virtual CPU devices)
sCpuCores = files.length > 0 ? files.length : 1;
} catch(Exception e) {
//Print exception
if (DEBUG) Log.d(TAG, "CPU Count: Failed.");
e.printStackTrace();
//Default to return 1 core
sCpuCores = 1;
}
return sCpuCores;
}
public static int getCpuMaxFreq() {
if (sCpuMaxFreq > 0)
return sCpuMaxFreq;
try {
final byte[] buffer = new byte[128];
FileInputStream is = new FileInputStream("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq");
int len = is.read(buffer);
is.close();
String str = new String(buffer, 0, len - 1);
sCpuMaxFreq = Integer.parseInt(str) / 1000;
} catch (IOException ex) {
ex.printStackTrace();
sCpuMaxFreq = 800;
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
sCpuMaxFreq = 800;
}
return sCpuMaxFreq;
}
/**
* GPU Information
*/
public static String getGlRenderer() {
return GLES10.glGetString(GLES10.GL_RENDERER);
}
/**
* Screen Information
*/
public static int getDisplayWidth() {
return sDisplayMetrics.widthPixels;
}
public static int getDisplayHeight() {
return sDisplayMetrics.heightPixels;
}
public static int getDisplayMaxWidth() {
return Math.max(sDisplayMetrics.widthPixels, sDisplayMetrics.heightPixels);
}
public static int getDisplayMinWidth() {
return Math.min(sDisplayMetrics.widthPixels, sDisplayMetrics.heightPixels);
}
public static int getDisplayRealWidth() {
return sDisplayRealMetrics.widthPixels;
}
public static int getDisplayRealHeight() {
return sDisplayRealMetrics.heightPixels;
}
public static int getDisplayRealMaxWidth() {
return Math.max(sDisplayRealMetrics.widthPixels, sDisplayRealMetrics.heightPixels);
}
public static int getDisplayRealMinWidth() {
return Math.min(sDisplayRealMetrics.widthPixels, sDisplayRealMetrics.heightPixels);
}
public static float getDisplayRefreshRate() {
return sDisplayRefreshRate;
}
public static boolean isTablet() {
return (sScreenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
}