1 package com.android.launcher3.util.rule; 2 3 import static androidx.test.InstrumentationRegistry.getInstrumentation; 4 5 import android.util.Log; 6 7 import androidx.test.uiautomator.UiDevice; 8 9 import org.junit.rules.TestWatcher; 10 import org.junit.runner.Description; 11 12 import java.io.ByteArrayOutputStream; 13 import java.io.File; 14 import java.io.IOException; 15 16 public class FailureWatcher extends TestWatcher { 17 private static final String TAG = "FailureWatcher"; 18 final private UiDevice mDevice; 19 FailureWatcher(UiDevice device)20 public FailureWatcher(UiDevice device) { 21 mDevice = device; 22 } 23 dumpViewHierarchy(UiDevice device)24 private static void dumpViewHierarchy(UiDevice device) { 25 final ByteArrayOutputStream stream = new ByteArrayOutputStream(); 26 try { 27 device.dumpWindowHierarchy(stream); 28 stream.flush(); 29 stream.close(); 30 for (String line : stream.toString().split("\\r?\\n")) { 31 Log.e(TAG, line.trim()); 32 } 33 } catch (IOException e) { 34 Log.e(TAG, "error dumping XML to logcat", e); 35 } 36 } 37 38 @Override failed(Throwable e, Description description)39 protected void failed(Throwable e, Description description) { 40 onError(mDevice, description, e); 41 } 42 onError(UiDevice device, Description description, Throwable e)43 public static void onError(UiDevice device, Description description, Throwable e) { 44 if (device == null) return; 45 final String pathname = getInstrumentation().getTargetContext(). 46 getFilesDir().getPath() + "/TestScreenshot-" + description.getMethodName() 47 + ".png"; 48 Log.e(TAG, "Failed test " + description.getMethodName() + 49 ", screenshot will be saved to " + pathname + 50 ", track trace is below, UI object dump is further below:\n" + 51 Log.getStackTraceString(e)); 52 dumpViewHierarchy(device); 53 54 try { 55 final String dumpsysResult = device.executeShellCommand( 56 "dumpsys activity service TouchInteractionService"); 57 Log.d(TAG, "TouchInteractionService: " + dumpsysResult); 58 } catch (IOException ex) { 59 } 60 61 device.takeScreenshot(new File(pathname)); 62 } 63 } 64