1 package com.android.uiautomator.core;
2 
3 import android.accessibilityservice.AccessibilityServiceInfo;
4 import android.app.UiAutomation;
5 import android.app.UiAutomation.AccessibilityEventFilter;
6 import android.app.UiAutomation.OnAccessibilityEventListener;
7 import android.graphics.Bitmap;
8 import android.util.Log;
9 import android.view.Display;
10 import android.view.InputEvent;
11 import android.view.accessibility.AccessibilityEvent;
12 import android.view.accessibility.AccessibilityNodeInfo;
13 
14 import java.io.BufferedOutputStream;
15 import java.io.File;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.util.concurrent.TimeoutException;
19 
20 /**
21  * @hide
22  */
23 public abstract class UiAutomatorBridge {
24 
25     private static final String LOG_TAG = UiAutomatorBridge.class.getSimpleName();
26 
27    /**
28     * This value has the greatest bearing on the appearance of test execution speeds.
29     * This value is used as the minimum time to wait before considering the UI idle after
30     * each action.
31     */
32     private static final long QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE = 500;//ms
33 
34    /**
35     * This is the maximum time the automation will wait for the UI to go idle. Execution
36     * will resume normally anyway. This is to prevent waiting forever on display updates
37     * that may be related to spinning wheels or progress updates of sorts etc...
38     */
39     private static final long TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE = 1000 * 10;//ms
40 
41     private final UiAutomation mUiAutomation;
42 
43     private final InteractionController mInteractionController;
44 
45     private final QueryController mQueryController;
46 
UiAutomatorBridge(UiAutomation uiAutomation)47     UiAutomatorBridge(UiAutomation uiAutomation) {
48         mUiAutomation = uiAutomation;
49         mInteractionController = new InteractionController(this);
50         mQueryController = new QueryController(this);
51     }
52 
getInteractionController()53     InteractionController getInteractionController() {
54         return mInteractionController;
55     }
56 
getQueryController()57     QueryController getQueryController() {
58         return mQueryController;
59     }
60 
setOnAccessibilityEventListener(OnAccessibilityEventListener listener)61     public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
62         mUiAutomation.setOnAccessibilityEventListener(listener);
63     }
64 
getRootInActiveWindow()65     public AccessibilityNodeInfo getRootInActiveWindow() {
66         return mUiAutomation.getRootInActiveWindow();
67     }
68 
injectInputEvent(InputEvent event, boolean sync)69     public boolean injectInputEvent(InputEvent event, boolean sync) {
70         return mUiAutomation.injectInputEvent(event, sync);
71     }
72 
setRotation(int rotation)73     public boolean setRotation(int rotation) {
74         return mUiAutomation.setRotation(rotation);
75     }
76 
setCompressedLayoutHierarchy(boolean compressed)77     public void setCompressedLayoutHierarchy(boolean compressed) {
78         AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
79         if (compressed)
80             info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
81         else
82             info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
83         mUiAutomation.setServiceInfo(info);
84     }
85 
getRotation()86     public abstract int getRotation();
87 
isScreenOn()88     public abstract boolean isScreenOn();
89 
waitForIdle()90     public void waitForIdle() {
91         waitForIdle(TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
92     }
93 
waitForIdle(long timeout)94     public void waitForIdle(long timeout) {
95         try {
96             mUiAutomation.waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);
97         } catch (TimeoutException te) {
98             Log.w(LOG_TAG, "Could not detect idle state.", te);
99         }
100     }
101 
executeCommandAndWaitForAccessibilityEvent(Runnable command, AccessibilityEventFilter filter, long timeoutMillis)102     public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
103             AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
104         return mUiAutomation.executeAndWaitForEvent(command,
105                 filter, timeoutMillis);
106     }
107 
takeScreenshot(File storePath, int quality)108     public boolean takeScreenshot(File storePath, int quality) {
109         Bitmap screenshot = mUiAutomation.takeScreenshot();
110         if (screenshot == null) {
111             return false;
112         }
113         BufferedOutputStream bos = null;
114         try {
115             bos = new BufferedOutputStream(new FileOutputStream(storePath));
116             if (bos != null) {
117                 screenshot.compress(Bitmap.CompressFormat.PNG, quality, bos);
118                 bos.flush();
119             }
120         } catch (IOException ioe) {
121             Log.e(LOG_TAG, "failed to save screen shot to file", ioe);
122             return false;
123         } finally {
124             if (bos != null) {
125                 try {
126                     bos.close();
127                 } catch (IOException ioe) {
128                     /* ignore */
129                 }
130             }
131             screenshot.recycle();
132         }
133         return true;
134     }
135 
performGlobalAction(int action)136     public boolean performGlobalAction(int action) {
137         return mUiAutomation.performGlobalAction(action);
138     }
139 
getDefaultDisplay()140     public abstract Display getDefaultDisplay();
141 
getSystemLongPressTime()142     public abstract long getSystemLongPressTime();
143 }
144