1package com.android.uiautomator.core;
2
3import android.accessibilityservice.AccessibilityServiceInfo;
4import android.app.UiAutomation;
5import android.app.UiAutomation.AccessibilityEventFilter;
6import android.app.UiAutomation.OnAccessibilityEventListener;
7import android.graphics.Bitmap;
8import android.util.Log;
9import android.view.Display;
10import android.view.InputEvent;
11import android.view.accessibility.AccessibilityEvent;
12import android.view.accessibility.AccessibilityNodeInfo;
13
14import java.io.BufferedOutputStream;
15import java.io.File;
16import java.io.FileOutputStream;
17import java.io.IOException;
18import java.util.concurrent.TimeoutException;
19
20/**
21 * @hide
22 */
23public 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
47    UiAutomatorBridge(UiAutomation uiAutomation) {
48        mUiAutomation = uiAutomation;
49        mInteractionController = new InteractionController(this);
50        mQueryController = new QueryController(this);
51    }
52
53    InteractionController getInteractionController() {
54        return mInteractionController;
55    }
56
57    QueryController getQueryController() {
58        return mQueryController;
59    }
60
61    public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
62        mUiAutomation.setOnAccessibilityEventListener(listener);
63    }
64
65    public AccessibilityNodeInfo getRootInActiveWindow() {
66        return mUiAutomation.getRootInActiveWindow();
67    }
68
69    public boolean injectInputEvent(InputEvent event, boolean sync) {
70        return mUiAutomation.injectInputEvent(event, sync);
71    }
72
73    public boolean setRotation(int rotation) {
74        return mUiAutomation.setRotation(rotation);
75    }
76
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
86    public abstract int getRotation();
87
88    public abstract boolean isScreenOn();
89
90    public void waitForIdle() {
91        waitForIdle(TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
92    }
93
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
102    public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
103            AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
104        return mUiAutomation.executeAndWaitForEvent(command,
105                filter, timeoutMillis);
106    }
107
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
136    public boolean performGlobalAction(int action) {
137        return mUiAutomation.performGlobalAction(action);
138    }
139
140    public abstract Display getDefaultDisplay();
141
142    public abstract long getSystemLongPressTime();
143}
144