118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupackage com.android.uiautomator.core;
218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.accessibilityservice.AccessibilityServiceInfo;
418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation;
518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation.AccessibilityEventFilter;
618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation.OnAccessibilityEventListener;
718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.graphics.Bitmap;
818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.Log;
918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.Display;
1018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.InputEvent;
1118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityEvent;
1218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityNodeInfo;
1318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
1418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.BufferedOutputStream;
1518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.File;
1618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.FileOutputStream;
1718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.IOException;
1818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.concurrent.TimeoutException;
1918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
2018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/**
2118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @hide
2218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */
2318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupublic abstract class UiAutomatorBridge {
2418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
2518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private static final String LOG_TAG = UiAutomatorBridge.class.getSimpleName();
2618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
2718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu   /**
2818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    * This value has the greatest bearing on the appearance of test execution speeds.
2918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    * This value is used as the minimum time to wait before considering the UI idle after
3018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    * each action.
3118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    */
3218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private static final long QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE = 500;//ms
3318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
3418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu   /**
3518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    * This is the maximum time the automation will wait for the UI to go idle. Execution
3618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    * will resume normally anyway. This is to prevent waiting forever on display updates
3718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    * that may be related to spinning wheels or progress updates of sorts etc...
3818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    */
3918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private static final long TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE = 1000 * 10;//ms
4018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
4118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private final UiAutomation mUiAutomation;
4218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
4318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private final InteractionController mInteractionController;
4418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
4518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    private final QueryController mQueryController;
4618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
4718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    UiAutomatorBridge(UiAutomation uiAutomation) {
4818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mUiAutomation = uiAutomation;
4918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mInteractionController = new InteractionController(this);
5018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mQueryController = new QueryController(this);
5118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
5218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
5318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    InteractionController getInteractionController() {
5418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mInteractionController;
5518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
5618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
5718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    QueryController getQueryController() {
5818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mQueryController;
5918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
6018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void setOnAccessibilityEventListener(OnAccessibilityEventListener listener) {
6218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mUiAutomation.setOnAccessibilityEventListener(listener);
6318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
6418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public AccessibilityNodeInfo getRootInActiveWindow() {
6618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mUiAutomation.getRootInActiveWindow();
6718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
6818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
6918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean injectInputEvent(InputEvent event, boolean sync) {
7018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mUiAutomation.injectInputEvent(event, sync);
7118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
7218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
7318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean setRotation(int rotation) {
7418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mUiAutomation.setRotation(rotation);
7518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
7618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
7718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void setCompressedLayoutHierarchy(boolean compressed) {
7818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
7918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (compressed)
8018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            info.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
8118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        else
8218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
8318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        mUiAutomation.setServiceInfo(info);
8418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
8518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
8618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public abstract int getRotation();
8718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
8818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public abstract boolean isScreenOn();
8918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
9018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void waitForIdle() {
9118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        waitForIdle(TOTAL_TIME_TO_WAIT_FOR_IDLE_STATE);
9218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
9318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
9418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public void waitForIdle(long timeout) {
9518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        try {
9618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            mUiAutomation.waitForIdle(QUIET_TIME_TO_BE_CONSIDERD_IDLE_STATE, timeout);
9718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        } catch (TimeoutException te) {
9818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            Log.w(LOG_TAG, "Could not detect idle state.", te);
9918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
10018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
10118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
10218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public AccessibilityEvent executeCommandAndWaitForAccessibilityEvent(Runnable command,
10318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            AccessibilityEventFilter filter, long timeoutMillis) throws TimeoutException {
10418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mUiAutomation.executeAndWaitForEvent(command,
10518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                filter, timeoutMillis);
10618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
10718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
10818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean takeScreenshot(File storePath, int quality) {
10918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        Bitmap screenshot = mUiAutomation.takeScreenshot();
11018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        if (screenshot == null) {
11118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            return false;
11218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
11318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        BufferedOutputStream bos = null;
11418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        try {
11518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            bos = new BufferedOutputStream(new FileOutputStream(storePath));
11618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            if (bos != null) {
11718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                screenshot.compress(Bitmap.CompressFormat.PNG, quality, bos);
11818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                bos.flush();
11918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            }
12018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        } catch (IOException ioe) {
12118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            Log.e(LOG_TAG, "failed to save screen shot to file", ioe);
12218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            return false;
12318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        } finally {
12418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            if (bos != null) {
12518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                try {
12618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    bos.close();
12718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                } catch (IOException ioe) {
12818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                    /* ignore */
12918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu                }
13018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            }
13118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu            screenshot.recycle();
13218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        }
13318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return true;
13418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
13518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
13618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public boolean performGlobalAction(int action) {
13718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu        return mUiAutomation.performGlobalAction(action);
13818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    }
13918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
14018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public abstract Display getDefaultDisplay();
14118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu
14218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu    public abstract long getSystemLongPressTime();
14318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu}
144