diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportCollector.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportCollector.java index f3c5bf7e5..068899224 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportCollector.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/BriarReportCollector.java @@ -7,7 +7,6 @@ package org.briarproject.briar.android.reporting; import android.annotation.SuppressLint; -import android.app.ActivityManager; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.pm.FeatureInfo; @@ -19,7 +18,6 @@ import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; -import android.os.Debug; import android.os.Environment; import org.briarproject.bramble.api.Pair; @@ -29,6 +27,7 @@ import org.briarproject.briar.R; import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo; import org.briarproject.briar.android.reporting.ReportData.ReportItem; import org.briarproject.briar.android.reporting.ReportData.SingleReportInfo; +import org.briarproject.briar.api.android.MemoryStats; import org.briarproject.briar.api.android.NetworkUsageMetrics; import org.briarproject.briar.api.android.NetworkUsageMetrics.Metrics; @@ -76,14 +75,14 @@ class BriarReportCollector { } ReportData collectReportData(@Nullable Throwable t, long appStartTime, - String logs) { + String logs, MemoryStats memoryStats) { ReportData reportData = new ReportData() .add(getBasicInfo(t)) .add(getDeviceInfo()); if (t != null) reportData.add(getStacktrace(t)); return reportData .add(getTimeInfo(appStartTime)) - .add(getMemory()) + .add(getMemory(memoryStats)) .add(getStorage()) .add(getConnectivity()) .add(getNetworkUsage()) @@ -154,26 +153,22 @@ class BriarReportCollector { return format.format(new Date(time)); } - private ReportItem getMemory() { + private ReportItem getMemory(MemoryStats stats) { MultiReportInfo memInfo = new MultiReportInfo(); // System memory - ActivityManager am = getSystemService(ctx, ActivityManager.class); - ActivityManager.MemoryInfo mem = new ActivityManager.MemoryInfo(); - requireNonNull(am).getMemoryInfo(mem); - memInfo.add("SystemMemoryTotal", mem.totalMem); - memInfo.add("SystemMemoryFree", mem.availMem); - memInfo.add("SystemMemoryThreshold", mem.threshold); - memInfo.add("SystemMemoryLow", mem.lowMemory); + memInfo.add("SystemMemoryTotal", stats.systemMemoryTotal); + memInfo.add("SystemMemoryFree", stats.systemMemoryFree); + memInfo.add("SystemMemoryThreshold", stats.systemMemoryThreshold); + memInfo.add("SystemMemoryLow", stats.systemMemoryLow); // Virtual machine memory - Runtime runtime = Runtime.getRuntime(); - memInfo.add("VirtualMachineMemoryTotal", runtime.totalMemory()); - memInfo.add("VirtualMachineMemoryFree", runtime.freeMemory()); - memInfo.add("VirtualMachineMemoryMaximum", runtime.maxMemory()); - memInfo.add("NativeHeapTotal", Debug.getNativeHeapSize()); - memInfo.add("NativeHeapAllocated", Debug.getNativeHeapAllocatedSize()); - memInfo.add("NativeHeapFree", Debug.getNativeHeapFreeSize()); + memInfo.add("VirtualMachineMemoryTotal", stats.vmMemoryTotal); + memInfo.add("VirtualMachineMemoryFree", stats.vmMemoryFree); + memInfo.add("VirtualMachineMemoryMaximum", stats.vmMemoryMax); + memInfo.add("NativeHeapTotal", stats.nativeHeapTotal); + memInfo.add("NativeHeapAllocated", stats.nativeHeapAllocated); + memInfo.add("NativeHeapFree", stats.nativeHeapFree); return new ReportItem("Memory", R.string.dev_report_memory, memInfo); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/CrashReportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/CrashReportActivity.java index 38dd7c545..fae4f2ada 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/CrashReportActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/CrashReportActivity.java @@ -15,6 +15,7 @@ import org.briarproject.briar.android.activity.BaseActivity; import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener; import org.briarproject.briar.android.logout.HideUiActivity; +import org.briarproject.briar.api.android.MemoryStats; import javax.inject.Inject; @@ -37,6 +38,7 @@ public class CrashReportActivity extends BaseActivity public static final String EXTRA_THROWABLE = "throwable"; public static final String EXTRA_APP_START_TIME = "appStartTime"; public static final String EXTRA_APP_LOGCAT = "logcat"; + public static final String EXTRA_MEMORY_STATS = "memoryStats"; @Inject ViewModelProvider.Factory viewModelFactory; @@ -60,7 +62,9 @@ public class CrashReportActivity extends BaseActivity Throwable t = (Throwable) intent.getSerializableExtra(EXTRA_THROWABLE); long appStartTime = intent.getLongExtra(EXTRA_APP_START_TIME, -1); byte[] logKey = intent.getByteArrayExtra(EXTRA_APP_LOGCAT); - viewModel.init(t, appStartTime, logKey, initialComment); + MemoryStats memoryStats = + (MemoryStats) intent.getSerializableExtra(EXTRA_MEMORY_STATS); + viewModel.init(t, appStartTime, logKey, initialComment, memoryStats); viewModel.getShowReport().observeEvent(this, show -> { if (show) displayFragment(true); }); @@ -87,7 +91,7 @@ public class CrashReportActivity extends BaseActivity exit(); } - void displayFragment(boolean showReportForm) { + private void displayFragment(boolean showReportForm) { BaseFragment f; if (showReportForm) { f = new ReportFormFragment(); @@ -101,7 +105,7 @@ public class CrashReportActivity extends BaseActivity .commit(); } - void exit() { + private void exit() { if (!viewModel.isFeedback()) { Intent i = new Intent(this, HideUiActivity.class); i.addFlags(FLAG_ACTIVITY_NEW_TASK diff --git a/briar-android/src/main/java/org/briarproject/briar/android/reporting/ReportViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/reporting/ReportViewModel.java index 24d71c31e..3ebd47097 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/reporting/ReportViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/reporting/ReportViewModel.java @@ -18,6 +18,7 @@ import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo; import org.briarproject.briar.android.reporting.ReportData.ReportItem; import org.briarproject.briar.android.viewmodel.LiveEvent; import org.briarproject.briar.android.viewmodel.MutableLiveEvent; +import org.briarproject.briar.api.android.MemoryStats; import org.briarproject.briar.api.android.NetworkUsageMetrics; import org.json.JSONException; @@ -84,7 +85,8 @@ class ReportViewModel extends AndroidViewModel { } void init(@Nullable Throwable t, long appStartTime, - @Nullable byte[] logKey, @Nullable String initialComment) { + @Nullable byte[] logKey, @Nullable String initialComment, + MemoryStats memoryStats) { this.initialComment = initialComment; isFeedback = t == null; if (reportData.getValue() == null) new SingleShotAndroidExecutor(() -> { @@ -102,8 +104,8 @@ class ReportViewModel extends AndroidViewModel { logHandler.getRecentLogRecords()); } } - ReportData data = - collector.collectReportData(t, appStartTime, decryptedLogs); + ReportData data = collector.collectReportData(t, appStartTime, + decryptedLogs, memoryStats); reportData.postValue(data); }).start(); } @@ -150,7 +152,7 @@ class ReportViewModel extends AndroidViewModel { /** * The content of the report that will be loaded after - * {@link #init(Throwable, long, byte[], String)} was called. + * {@link #init(Throwable, long, byte[], String, MemoryStats)} was called. */ LiveData getReportData() { return reportData; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index 040ca0025..0952431bc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -1,6 +1,8 @@ package org.briarproject.briar.android.util; import android.app.Activity; +import android.app.ActivityManager; +import android.app.ActivityManager.MemoryInfo; import android.app.KeyguardManager; import android.content.ActivityNotFoundException; import android.content.Context; @@ -10,6 +12,7 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.location.LocationManager; import android.net.Uri; +import android.os.Debug; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; @@ -38,6 +41,7 @@ import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.R; import org.briarproject.briar.android.reporting.FeedbackActivity; import org.briarproject.briar.android.view.ArticleMovementMethod; +import org.briarproject.briar.api.android.MemoryStats; import java.util.Locale; import java.util.logging.Logger; @@ -113,6 +117,7 @@ import static org.briarproject.briar.android.TestingConstants.OLD_ANDROID_WARN_D import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_LOGCAT; import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_START_TIME; import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_INITIAL_COMMENT; +import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_MEMORY_STATS; import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_THROWABLE; @MethodsNotNullByDefault @@ -429,12 +434,27 @@ public class UiUtils { Class activity, @Nullable Throwable t, @Nullable Long appStartTime, @Nullable byte[] logKey, @Nullable String initialComment) { + // Collect memory stats from the current process, not the crash + // reporter process + ActivityManager am = + requireNonNull(getSystemService(ctx, ActivityManager.class)); + MemoryInfo mem = new MemoryInfo(); + am.getMemoryInfo(mem); + Runtime runtime = Runtime.getRuntime(); + MemoryStats memoryStats = new MemoryStats(mem.totalMem, + mem.availMem, mem.threshold, mem.lowMemory, + runtime.totalMemory(), runtime.freeMemory(), + runtime.maxMemory(), Debug.getNativeHeapSize(), + Debug.getNativeHeapAllocatedSize(), + Debug.getNativeHeapFreeSize()); + final Intent dialogIntent = new Intent(ctx, activity); dialogIntent.setFlags(FLAG_ACTIVITY_NEW_TASK); dialogIntent.putExtra(EXTRA_THROWABLE, t); dialogIntent.putExtra(EXTRA_APP_START_TIME, appStartTime); dialogIntent.putExtra(EXTRA_APP_LOGCAT, logKey); dialogIntent.putExtra(EXTRA_INITIAL_COMMENT, initialComment); + dialogIntent.putExtra(EXTRA_MEMORY_STATS, memoryStats); ctx.startActivity(dialogIntent); } diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/MemoryStats.java b/briar-android/src/main/java/org/briarproject/briar/api/android/MemoryStats.java new file mode 100644 index 000000000..8378e92ba --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/api/android/MemoryStats.java @@ -0,0 +1,42 @@ +package org.briarproject.briar.api.android; + +import java.io.Serializable; + +import javax.annotation.concurrent.Immutable; + +/** + * Memory usage stats to be included in feedback and crash reports. This class + * is {@link Serializable} so it can be passed from the crashed process to the + * crash reporter process. + */ +@Immutable +public class MemoryStats implements Serializable { + + public final long systemMemoryTotal; + public final long systemMemoryFree; + public final long systemMemoryThreshold; + public final boolean systemMemoryLow; + public final long vmMemoryTotal; + public final long vmMemoryFree; + public final long vmMemoryMax; + public final long nativeHeapTotal; + public final long nativeHeapAllocated; + public final long nativeHeapFree; + + public MemoryStats(long systemMemoryTotal, long systemMemoryFree, + long systemMemoryThreshold, boolean systemMemoryLow, + long vmMemoryTotal, long vmMemoryFree, long vmMemoryMax, + long nativeHeapTotal, long nativeHeapAllocated, + long nativeHeapFree) { + this.systemMemoryTotal = systemMemoryTotal; + this.systemMemoryFree = systemMemoryFree; + this.systemMemoryThreshold = systemMemoryThreshold; + this.systemMemoryLow = systemMemoryLow; + this.vmMemoryTotal = vmMemoryTotal; + this.vmMemoryFree = vmMemoryFree; + this.vmMemoryMax = vmMemoryMax; + this.nativeHeapTotal = nativeHeapTotal; + this.nativeHeapAllocated = nativeHeapAllocated; + this.nativeHeapFree = nativeHeapFree; + } +}