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