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