diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java index 4c4794789e..dc59bddabd 100644 --- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java +++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java @@ -2,6 +2,8 @@ package com.android.launcher3.util.rule; import static androidx.test.InstrumentationRegistry.getInstrumentation; +import android.os.FileUtils; +import android.os.ParcelFileDescriptor.AutoCloseInputStream; import android.util.Log; import androidx.test.uiautomator.UiDevice; @@ -12,9 +14,12 @@ import com.android.launcher3.ui.AbstractLauncherUiTest; import org.junit.rules.TestWatcher; import org.junit.runner.Description; -import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; public class FailureWatcher extends TestWatcher { private static final String TAG = "FailureWatcher"; @@ -26,20 +31,6 @@ public class FailureWatcher extends TestWatcher { mLauncher = launcher; } - private static void dumpViewHierarchy(UiDevice device) { - final ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - device.dumpWindowHierarchy(stream); - stream.flush(); - stream.close(); - for (String line : stream.toString().split("\\r?\\n")) { - Log.e(TAG, line.trim()); - } - } catch (IOException e) { - Log.e(TAG, "error dumping XML to logcat", e); - } - } - @Override protected void succeeded(Description description) { super.succeeded(description); @@ -53,22 +44,41 @@ public class FailureWatcher extends TestWatcher { public static void onError(UiDevice device, Description description, Throwable e) { if (device == null) return; - final String pathname = getInstrumentation().getTargetContext(). - getFilesDir().getPath() + "/TestScreenshot-" + description.getMethodName() - + ".png"; - Log.e(TAG, "Failed test " + description.getMethodName() + - ", screenshot will be saved to " + pathname + - ", track trace is below, UI object dump is further below:\n" + - Log.getStackTraceString(e)); - dumpViewHierarchy(device); + final File parentFile = getInstrumentation().getTargetContext().getFilesDir(); + final File sceenshot = new File(parentFile, + "TestScreenshot-" + description.getMethodName() + ".png"); + final File hierarchy = new File(parentFile, + "Hierarchy-" + description.getMethodName() + ".zip"); - try { - final String dumpsysResult = device.executeShellCommand( - "dumpsys activity service TouchInteractionService"); - Log.d(TAG, "TouchInteractionService: " + dumpsysResult); - } catch (IOException ex) { + // Dump window hierarchy + try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(hierarchy))) { + out.putNextEntry(new ZipEntry("bugreport.txt")); + dumpStringCommand("dumpsys window windows", out); + dumpStringCommand("dumpsys package", out); + dumpStringCommand("dumpsys activity service TouchInteractionService", out); + out.closeEntry(); + + out.putNextEntry(new ZipEntry("visible_windows.zip")); + dumpCommand("cmd window dump-visible-window-views", out); + out.closeEntry(); + } catch (IOException ex) { } + + Log.e(TAG, "Failed test " + description.getMethodName() + + ",\nscreenshot will be saved to " + sceenshot + + ",\nUI dump at: " + hierarchy + + " (use go/web-hv to open the dump file)", e); + device.takeScreenshot(sceenshot); + } + + private static void dumpStringCommand(String cmd, OutputStream out) throws IOException { + out.write(("\n\n" + cmd + "\n").getBytes()); + dumpCommand(cmd, out); + } + + private static void dumpCommand(String cmd, OutputStream out) throws IOException { + try (AutoCloseInputStream in = new AutoCloseInputStream(getInstrumentation() + .getUiAutomation().executeShellCommand(cmd))) { + FileUtils.copy(in, out); } - - device.takeScreenshot(new File(pathname)); } }