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