1e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupackage com.android.uiautomator.core;
2e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
34a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtazimport android.accessibilityservice.AccessibilityServiceInfo;
489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.app.UiAutomation;
5df721e515f18e753ad817e65d60bfe1dcfb01ab7Svetoslavimport android.app.UiAutomation.AccessibilityEventFilter;
689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.app.UiAutomation.OnAccessibilityEventListener;
789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.graphics.Bitmap;
8e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.util.Log;
989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.view.Display;
1089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.view.InputEvent;
11e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.view.accessibility.AccessibilityEvent;
1289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo;
1389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov
1489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport java.io.BufferedOutputStream;
1589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport java.io.File;
1689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport java.io.FileOutputStream;
1789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganovimport java.io.IOException;
18e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport java.util.concurrent.TimeoutException;
19e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
20cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu/**
21cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu * @hide
22cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu */
23cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhupublic abstract class UiAutomatorBridge {
24e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
2589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    private static final String LOG_TAG = UiAutomatorBridge.class.getSimpleName();
26e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
2789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov   /**
2889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    * This value has the greatest bearing on the appearance of test execution speeds.
2989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    * This value is used as the minimum time to wait before considering the UI idle after
3089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    * each action.
3189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    */
32e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private static final long QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE = 500;//ms
33e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
3489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov   /**
3589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    * This is the maximum time the automation will wait for the UI to go idle. Execution
3689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    * will resume normally anyway. This is to prevent waiting forever on display updates
3789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    * that may be related to spinning wheels or progress updates of sorts etc...
3889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    */
39e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private static final long TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE = 1000 * 10;//ms
40e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
4189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    private final UiAutomation mUiAutomation;
42e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
43e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private final InteractionController mInteractionController;
44e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
45e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    private final QueryController mQueryController;
46e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
4789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    UiAutomatorBridge(UiAutomation uiAutomation) {
4889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        mUiAutomation = uiAutomation;
49e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        mInteractionController = new InteractionController(this);
50e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        mQueryController = new QueryController(this);
51e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
52e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
53e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    InteractionController getInteractionController() {
54e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return mInteractionController;
55e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
56e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
57e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    QueryController getQueryController() {
58e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        return mQueryController;
59e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
60e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
6189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
6289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        mUiAutomation.setOnAccessibilityEventListener(listener);
63e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
6589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public AccessibilityNodeInfo getRootInActiveWindow() {
6689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        return mUiAutomation.getRootInActiveWindow();
67e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
68e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
6989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public boolean injectInputEvent(InputEvent event, boolean sync) {
7089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        return mUiAutomation.injectInputEvent(event, sync);
71e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
72e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
7389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public boolean setRotation(int rotation) {
7489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        return mUiAutomation.setRotation(rotation);
75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
76e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
774a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz    public void setCompressedLayoutHierarchy(boolean compressed) {
784a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
794a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz        if (compressed)
804a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
814a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz        else
824a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
834a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz        mUiAutomation.setServiceInfo(info);
844a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz    }
854a82ca385244ade0d9a5654d7eb3b7797846a6dbAdam Momtaz
86cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu    public abstract int getRotation();
87cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu
88cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu    public abstract boolean isScreenOn();
89cd08ab4b0d19e68cc1cf18396cb9076e828c1a63Guang Zhu
9089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public void waitForIdle() {
9189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        waitForIdle(TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
92e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
93e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
9489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public void waitForIdle(long timeout) {
9589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        try {
9689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            mUiAutomation.waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);
9789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        } catch (TimeoutException te) {
9889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            Log.w(LOG_TAG, "Could not detect idle state.", te);
99e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
100e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
10289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
103df721e515f18e753ad817e65d60bfe1dcfb01ab7Svetoslav            AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
10489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        return mUiAutomation.executeAndWaitForEvent(command,
10589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                filter, timeoutMillis);
106e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
107e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu
10889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public boolean takeScreenshot(File storePath, int quality) {
10989f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        Bitmap screenshot = mUiAutomation.takeScreenshot();
11089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        if (screenshot == null) {
11189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            return false;
112e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
11389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        BufferedOutputStream bos = null;
11489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        try {
11589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            bos = new BufferedOutputStream(new FileOutputStream(storePath));
11689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            if (bos != null) {
11789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                screenshot.compress(Bitmap.CompressFormat.PNG, quality, bos);
11889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                bos.flush();
119e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
12089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        } catch (IOException ioe) {
12189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            Log.e(LOG_TAG, "failed to save screen shot to file", ioe);
12289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            return false;
12389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        } finally {
12489f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            if (bos != null) {
12589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                try {
12689f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                    bos.close();
12789f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                } catch (IOException ioe) {
12889f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov                    /* ignore */
129e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu                }
130e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu            }
13189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov            screenshot.recycle();
132e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu        }
13389f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov        return true;
134e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu    }
13589f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov
136de8b8de6708daa3c0759adf5dad7b18a1b86402bGuang Zhu    public boolean performGlobalAction(int action) {
137de8b8de6708daa3c0759adf5dad7b18a1b86402bGuang Zhu        return mUiAutomation.performGlobalAction(action);
138de8b8de6708daa3c0759adf5dad7b18a1b86402bGuang Zhu    }
139de8b8de6708daa3c0759adf5dad7b18a1b86402bGuang Zhu
14089f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public abstract Display getDefaultDisplay();
14189f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov
14289f6117cb1fbeab3770106cf54e05af1f597be81Svetoslav Ganov    public abstract long getSystemLongPressTime();
143e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu}
144