Chromium Code Reviews| Index: base/android/java/src/org/chromium/base/SysUtils.java |
| diff --git a/base/android/java/src/org/chromium/base/SysUtils.java b/base/android/java/src/org/chromium/base/SysUtils.java |
| index 7af5a40069af8aaf09f499f2a2849aa73cc1576b..c100aee23e49e6da7dbfe8ccab61e7c82f356d16 100644 |
| --- a/base/android/java/src/org/chromium/base/SysUtils.java |
| +++ b/base/android/java/src/org/chromium/base/SysUtils.java |
| @@ -4,27 +4,109 @@ |
| package org.chromium.base; |
| +import java.io.BufferedReader; |
| +import java.io.FileReader; |
| +import java.util.regex.Matcher; |
| +import java.util.regex.Pattern; |
| + |
| import android.app.ActivityManager; |
| import android.app.ActivityManager.MemoryInfo; |
| import android.content.Context; |
| import android.os.Build; |
| +import android.util.Log; |
| /** |
| * Exposes system related information about the current device. |
| */ |
| public class SysUtils { |
| + // Any device that runs this or an older version of the system cannot be considered 'low-end' |
| + private static final int ANDROID_LOW_MEMORY_ANDROID_SDK_THRESHOLD = |
| + Build.VERSION_CODES.JELLY_BEAN_MR2; |
| + |
| + // A device reporting strictly more total memory in megabytes cannot be considered 'low-end'. |
| + private static final long ANDROID_LOW_MEMORY_DEVICE_THRESHOLD_MB = 512; |
| + |
| + private static final String TAG = "SysUtils"; |
| + |
| private static Boolean sLowEndDevice; |
| private SysUtils() { } |
| /** |
| + * Return the amount of physical memory on this device in kilobytes. |
| + * Note: the only reason this is public is for testability reason. |
| + * @return Amount of physical memory in kilobytes, or 0 if there was |
| + * an error trying to access the information. |
| + * |
| + * Note that this is CalledByNative for testing purpose only. |
| + */ |
| + @CalledByNative |
| + public static int amountOfPhysicalMemoryKB() { |
|
jdduke (slow)
2013/11/08 16:41:01
If the query is restricted to JB+ devices, why are
digit1
2013/11/08 16:49:06
This is covered by lines 50-55, in short: it's too
|
| + // Extract total memory RAM size by parsing /proc/meminfo, note that |
| + // this is exactly what the implementation of sysconf(_SC_PHYS_PAGES) |
| + // does. However, it can't be called because this method must be |
| + // usable before any native code is loaded. |
| + |
| + // An alternative is to use ActivityManager.getMemoryInfo(), but this |
| + // requires a valid ActivityManager handle, which can only come from |
| + // a valid Context object, which itself cannot be retrieved |
| + // during early startup, where this method is called. And making it |
| + // an explicit parameter here makes all call paths _much_ more |
| + // complicated. |
| + |
| + Pattern pattern = Pattern.compile("^MemTotal:\\s+([0-9]+) kB$"); |
| + try { |
| + FileReader fileReader = new FileReader("/proc/meminfo"); |
| + try { |
| + BufferedReader reader = new BufferedReader(fileReader); |
| + try { |
| + String line; |
| + for (;;) { |
| + line = reader.readLine(); |
| + if (line == null) { |
| + Log.w(TAG, "/proc/meminfo lacks a MemTotal entry?"); |
| + break; |
| + } |
| + Matcher m = pattern.matcher(line); |
| + if (!m.find()) continue; |
| + |
| + int totalMemoryKB = Integer.parseInt(m.group(1)); |
| + // Sanity check. |
| + if (totalMemoryKB <= 1024) { |
| + Log.w(TAG, "Invalid /proc/meminfo total size in kB: " + m.group(1)); |
| + break; |
| + } |
| + |
| + return totalMemoryKB; |
| + } |
| + |
| + } finally { |
| + reader.close(); |
| + } |
| + } finally { |
| + fileReader.close(); |
| + } |
| + } catch (Exception e) { |
| + Log.w(TAG, "Cannot get total physical size from /proc/meminfo", e); |
| + } |
| + |
| + return 0; |
| + } |
| + |
| + /** |
| * @return Whether or not this device should be considered a low end device. |
| */ |
| + @CalledByNative |
| public static boolean isLowEndDevice() { |
| - if (sLowEndDevice == null) sLowEndDevice = nativeIsLowEndDevice(); |
| + if (Build.VERSION.SDK_INT <= ANDROID_LOW_MEMORY_ANDROID_SDK_THRESHOLD) { |
| + return false; |
| + } |
| + if (sLowEndDevice == null) { |
| + int ramSizeKB = amountOfPhysicalMemoryKB(); |
| + sLowEndDevice = (ramSizeKB > 0 && |
| + ramSizeKB * 1024 < ANDROID_LOW_MEMORY_DEVICE_THRESHOLD_MB); |
| + } |
| return sLowEndDevice.booleanValue(); |
| } |
| - |
| - private static native boolean nativeIsLowEndDevice(); |
| } |