Adding system health diags for OOP tests

Bug: 133891845
Change-Id: I24aa2b1408b3ffe4105cd4a7892c8b5fec8740e1
diff --git a/tests/tapl/AndroidManifest.xml b/tests/tapl/AndroidManifest.xml
index 0207e2b..1065446 100644
--- a/tests/tapl/AndroidManifest.xml
+++ b/tests/tapl/AndroidManifest.xml
@@ -23,4 +23,6 @@
 >
 
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
+    <uses-permission android:name="android.permission.READ_LOGS"/>
+    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
 </manifest>
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index c613ed5..55ccb1c 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -39,6 +39,7 @@
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.DropBoxManager;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.text.TextUtils;
@@ -274,14 +275,96 @@
         return null;
     }
 
+    private static String truncateCrash(String text, int maxLines) {
+        String[] lines = text.split("\\r?\\n");
+        StringBuilder ret = new StringBuilder();
+        for (int i = 0; i < maxLines && i < lines.length; i++) {
+            ret.append(lines[i]);
+            ret.append('\n');
+        }
+        if (lines.length > maxLines) {
+            ret.append("... ");
+            ret.append(lines.length - maxLines);
+            ret.append(" more lines truncated ...\n");
+        }
+        return ret.toString();
+    }
+
+    private String checkCrash(String label) {
+        DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService(
+                Context.DROPBOX_SERVICE);
+        Assert.assertNotNull("Unable access the DropBoxManager service", dropbox);
+
+        long timestamp = 0;
+        DropBoxManager.Entry entry;
+        int crashCount = 0;
+        StringBuilder errorDetails = new StringBuilder();
+        while (null != (entry = dropbox.getNextEntry(label, timestamp))) {
+            String dropboxSnippet;
+            try {
+                dropboxSnippet = entry.getText(4096);
+            } finally {
+                entry.close();
+            }
+
+            crashCount++;
+            errorDetails.append(label);
+            errorDetails.append(": ");
+            errorDetails.append(truncateCrash(dropboxSnippet, 40));
+            errorDetails.append("    ...\n");
+
+            timestamp = entry.getTimeMillis();
+        }
+        Assert.assertEquals(errorDetails.toString(), 0, crashCount);
+        return crashCount > 0 ? errorDetails.toString() : null;
+    }
+
+    private String getSystemHealthMessage() {
+        try {
+            StringBuilder errors = new StringBuilder();
+
+            final String testPackage = getContext().getPackageName();
+            try {
+                mDevice.executeShellCommand("pm grant " + testPackage +
+                        " android.permission.READ_LOGS");
+                mDevice.executeShellCommand("pm grant " + testPackage +
+                        " android.permission.PACKAGE_USAGE_STATS");
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+            final String[] labels = {
+                    "system_server_crash",
+                    "system_server_native_crash",
+                    "system_server_anr",
+            };
+
+            for (String label : labels) {
+                final String crash = checkCrash(label);
+                if (crash != null) errors.append(crash);
+            }
+
+            return errors.length() != 0 ? errors.toString() : null;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     private void fail(String message) {
         message = "http://go/tapl : " + getContextDescription() + message;
 
         final String anomaly = getAnomalyMessage();
         if (anomaly != null) message = anomaly + ", which causes:\n" + message;
 
+        final String systemHealth = getSystemHealthMessage();
+        if (systemHealth != null) {
+            message = message + ", which might be a consequence of system health problems:\n<<<\n"
+                    + systemHealth + "\n>>>";
+        }
+
         log("Hierarchy dump for: " + message);
         dumpViewHierarchy();
+
         Assert.fail(message);
     }