Bug 894567: Use MemoryInfo.totalMem to get the device's total memory rather than parse /proc/meminfo. r=nalexander

Differential Revision: https://phabricator.services.mozilla.com/D33549

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Will Hawkins 2019-06-04 19:41:06 +00:00
Родитель a877dfb56a
Коммит c5c101d201
4 изменённых файлов: 32 добавлений и 103 удалений

Просмотреть файл

@ -300,7 +300,7 @@ public final class ANRReporter extends BroadcastReceiver
return data.length;
}
private static void fillPingHeader(OutputStream ping, String slug)
private static void fillPingHeader(Context context, OutputStream ping, String slug)
throws IOException {
// ping file header
@ -332,7 +332,7 @@ public final class ANRReporter extends BroadcastReceiver
"\"platformBuildID\":" + JSONObject.quote(AppConstants.MOZ_APP_BUILDID) + "," +
"\"locale\":" + JSONObject.quote(Locales.getLanguageTag(Locale.getDefault())) + "," +
"\"cpucount\":" + String.valueOf(SysInfo.getCPUCount()) + "," +
"\"memsize\":" + String.valueOf(SysInfo.getMemSize()) + "," +
"\"memsize\":" + String.valueOf(SysInfo.getMemSize(context)) + "," +
"\"arch\":" + JSONObject.quote(SysInfo.getArchABI()) + "," +
"\"kernel_version\":" + JSONObject.quote(SysInfo.getKernelVersion()) + "," +
"\"device\":" + JSONObject.quote(SysInfo.getDevice()) + "," +
@ -479,19 +479,19 @@ public final class ANRReporter extends BroadcastReceiver
}
}
private static void processTraces(Reader traces, File pingFile) {
private static void processTraces(Context context, Reader traces, File pingFile) {
// Only get native stack if Gecko is running.
// Also, unwinding is memory intensive, so only unwind if we have enough memory.
final boolean haveNativeStack =
GeckoThread.isRunning() ?
requestNativeStack(/* unwind */ SysInfo.getMemSize() >= 640) : false;
requestNativeStack(/* unwind */ SysInfo.getMemSize(context) >= 640) : false;
try {
OutputStream ping = new BufferedOutputStream(
new FileOutputStream(pingFile), TRACES_BLOCK_SIZE);
try {
fillPingHeader(ping, pingFile.getName());
fillPingHeader(context, ping, pingFile.getName());
// Traces file has the format
// ----- pid xxx at xxx -----
// Cmd line: org.mozilla.xxx
@ -527,12 +527,12 @@ public final class ANRReporter extends BroadcastReceiver
}
}
private static void processTraces(File tracesFile, File pingFile) {
private static void processTraces(Context context, File tracesFile, File pingFile) {
try {
Reader traces = new InputStreamReader(
new FileInputStream(tracesFile), TRACES_CHARSET);
try {
processTraces(traces, pingFile);
processTraces(context, traces, pingFile);
} finally {
traces.close();
}
@ -596,6 +596,6 @@ public final class ANRReporter extends BroadcastReceiver
return;
}
Log.i(LOGTAG, "processing Gecko ANR");
processTraces(tracesFile, pingFile);
processTraces(context, tracesFile, pingFile);
}
}

Просмотреть файл

@ -1036,8 +1036,8 @@ public class GeckoAppShell {
return sDensity;
}
private static boolean isHighMemoryDevice() {
return HardwareUtils.getMemSize() > HIGH_MEMORY_DEVICE_THRESHOLD_MB;
private static boolean isHighMemoryDevice(final Context context) {
return SysInfo.getMemSize(context) > HIGH_MEMORY_DEVICE_THRESHOLD_MB;
}
public static synchronized void useMaxScreenDepth(final boolean enable) {
@ -1052,11 +1052,11 @@ public class GeckoAppShell {
public static synchronized int getScreenDepth() {
if (sScreenDepth == 0) {
sScreenDepth = 16;
final Context applicationContext = getApplicationContext();
PixelFormat info = new PixelFormat();
final WindowManager wm = (WindowManager)
getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
final WindowManager wm = (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE);
PixelFormat.getPixelFormatInfo(wm.getDefaultDisplay().getPixelFormat(), info);
if (info.bitsPerPixel >= 24 && isHighMemoryDevice()) {
if (info.bitsPerPixel >= 24 && isHighMemoryDevice(applicationContext)) {
sScreenDepth = sUseMaxScreenDepth ? info.bitsPerPixel : 24;
}
}

Просмотреть файл

@ -5,15 +5,15 @@
package org.mozilla.gecko;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.util.Log;
import org.mozilla.gecko.util.StrictModeContext;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.regex.Pattern;
@ -77,96 +77,30 @@ public final class SysInfo {
}
/**
* Helper functions used to extract key/value data from /proc/meminfo
* Pulled from:
* http://androidxref.com/4.2_r1/xref/frameworks/base/core/java/com/android/internal/util/MemInfoReader.java
* Fetch the total memory of the device in MB.
*
* NB: This cannot be called before GeckoAppShell has been
* initialized.
*
* @return Memory size in MB.
*/
private static boolean matchMemText(final byte[] buffer, final int index,
final int bufferLength, final byte[] text) {
final int N = text.length;
if ((index + N) >= bufferLength) {
return false;
}
for (int i = 0; i < N; i++) {
if (buffer[index + i] != text[i]) {
return false;
}
}
return true;
}
/**
* Parses a line like:
*
* MemTotal: 1605324 kB
*
* into 1605324.
*
* @return the first uninterrupted sequence of digits following the
* specified index, parsed as an integer value in KB.
*/
private static int extractMemValue(final byte[] buffer, final int offset, final int length) {
if (offset >= length) {
return 0;
}
int i = offset;
while (i < length && buffer[i] != '\n') {
if (buffer[i] >= '0' && buffer[i] <= '9') {
int start = i++;
while (i < length && buffer[i] >= '0' && buffer[i] <= '9') {
++i;
}
return Integer.parseInt(new String(buffer, start, i - start), 10);
}
++i;
}
return 0;
}
/**
* 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.
*/
@SuppressWarnings("try")
public static int getMemSize() {
public static int getMemSize(final Context context) {
if (totalRAM >= 0) {
return totalRAM;
}
// This is the string "MemTotal" that we're searching for in the buffer.
final byte[] MEMTOTAL = {'M', 'e', 'm', 'T', 'o', 't', 'a', 'l'};
final MemoryInfo memInfo = new MemoryInfo();
// `/proc/meminfo` is not a real file and thus safe to read on the main thread.
try (StrictModeContext unused = StrictModeContext.allowDiskReads()) {
final byte[] buffer = new byte[MEMINFO_BUFFER_SIZE_BYTES];
final FileInputStream is = new FileInputStream("/proc/meminfo");
try {
final int length = is.read(buffer);
final ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
am.getMemoryInfo(memInfo);
// `getMemoryInfo()` returns a value in B. Convert to MB.
totalRAM = (int)(memInfo.totalMem / (1024 * 1024));
for (int i = 0; i < length; i++) {
if (matchMemText(buffer, i, length, MEMTOTAL)) {
i += 8;
totalRAM = extractMemValue(buffer, i, length) / 1024;
Log.d(LOG_TAG, "System memory: " + totalRAM + "MB.");
return totalRAM;
}
}
} finally {
is.close();
}
Log.w(LOG_TAG, "Did not find MemTotal line in /proc/meminfo.");
return totalRAM = 0;
} catch (FileNotFoundException f) {
return totalRAM = 0;
} catch (IOException e) {
return totalRAM = 0;
}
return totalRAM;
}
/**

Просмотреть файл

@ -12,7 +12,6 @@ import android.os.Build;
import android.system.Os;
import android.util.Log;
import org.mozilla.gecko.SysInfo;
import org.mozilla.geckoview.BuildConfig;
import java.io.File;
@ -79,10 +78,6 @@ public final class HardwareUtils {
return sIsTelevision;
}
public static int getMemSize() {
return SysInfo.getMemSize();
}
private static String getPreferredAbi() {
String abi = null;
if (Build.VERSION.SDK_INT >= 21) {