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(); |
} |