118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/* 218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Copyright (C) 2012 The Android Open Source Project 318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * you may not use this file except in compliance with the License. 618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You may obtain a copy of the License at 718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 1018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Unless required by applicable law or agreed to in writing, software 1118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 1218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See the License for the specific language governing permissions and 1418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * limitations under the License. 1518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 1618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupackage com.android.uiautomator.core; 1818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 1918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation; 2018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.app.UiAutomation.AccessibilityEventFilter; 2118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.graphics.Point; 2218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Build; 2318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.Environment; 2418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.RemoteException; 2518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.os.SystemClock; 2618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.DisplayMetrics; 2718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.util.Log; 2818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.Display; 2918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.KeyEvent; 3018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.Surface; 3118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityEvent; 3218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport android.view.accessibility.AccessibilityNodeInfo; 3318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 3418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.io.File; 3518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.ArrayList; 3618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.HashMap; 3718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.List; 3818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhuimport java.util.concurrent.TimeoutException; 3918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 4018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu/** 4118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * UiDevice provides access to state information about the device. 4218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You can also use this class to simulate user actions on the device, 4318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * such as pressing the d-pad or pressing the Home and Menu buttons. 4418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 4518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 4618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhupublic class UiDevice { 4718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final String LOG_TAG = UiDevice.class.getSimpleName(); 4818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 4918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // Sometimes HOME and BACK key presses will generate no events if already on 5018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // home page or there is nothing to go back to, Set low timeouts. 5118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static final long KEY_PRESS_EVENT_TIMEOUT = 1 * 1000; 5218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 5318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // store for registered UiWatchers 5418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private final HashMap<String, UiWatcher> mWatchers = new HashMap<String, UiWatcher>(); 5518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private final List<String> mWatchersTriggers = new ArrayList<String>(); 5618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 5718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // remember if we're executing in the context of a UiWatcher 5818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private boolean mInWatcherContext = false; 5918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // provides access the {@link QueryController} and {@link InteractionController} 6118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiAutomatorBridge mUiAutomationBridge; 6218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // reference to self 6418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private static UiDevice sDevice; 6518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 6618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private UiDevice() { 6718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /* hide constructor */ 6818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 6918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 7018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 7118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @hide 7218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 7318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void initialize(UiAutomatorBridge uiAutomatorBridge) { 7418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mUiAutomationBridge = uiAutomatorBridge; 7518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 7618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 7718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu boolean isInWatcherContext() { 7818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return mInWatcherContext; 7918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 8018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 8118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 8218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Provides access the {@link QueryController} and {@link InteractionController} 8318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return {@link ShellUiAutomatorBridge} 8418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 8518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiAutomatorBridge getAutomatorBridge() { 8618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mUiAutomationBridge == null) { 8718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu throw new RuntimeException("UiDevice not initialized"); 8818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 8918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return mUiAutomationBridge; 9018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 9118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 9218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 9318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Enables or disables layout hierarchy compression. 9418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 9518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If compression is enabled, the layout hierarchy derived from the Acessibility 9618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * framework will only contain nodes that are important for uiautomator 9718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * testing. Any unnecessary surrounding layout nodes that make viewing 9818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * and searching the hierarchy inefficient are removed. 9918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 10018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param compressed true to enable compression; else, false to disable 10118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 10218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 10318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void setCompressedLayoutHeirarchy(boolean compressed) { 10418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().setCompressedLayoutHierarchy(compressed); 10518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 10618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 10718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 10818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Retrieves a singleton instance of UiDevice 10918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 11018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return UiDevice instance 11118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 11218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 11318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public static UiDevice getInstance() { 11418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (sDevice == null) { 11518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu sDevice = new UiDevice(); 11618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return sDevice; 11818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 11918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 12018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 12118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Returns the display size in dp (device-independent pixel) 12218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 12318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The returned display size is adjusted per screen rotation. Also this will return the actual 12418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * size of the screen, rather than adjusted per system decorations (like status bar). 12518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 12618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return a Point containing the display size in dp 12718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 12818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public Point getDisplaySizeDp() { 12918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 13018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Display display = getAutomatorBridge().getDefaultDisplay(); 13118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Point p = new Point(); 13218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu display.getRealSize(p); 13318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu DisplayMetrics metrics = new DisplayMetrics(); 13418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu display.getRealMetrics(metrics); 13518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu float dpx = p.x / metrics.density; 13618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu float dpy = p.y / metrics.density; 13718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu p.x = Math.round(dpx); 13818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu p.y = Math.round(dpy); 13918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return p; 14018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 14118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 14218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 14318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Retrieves the product name of the device. 14418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 14518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * This method provides information on what type of device the test is running on. This value is 14618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the same as returned by invoking #adb shell getprop ro.product.name. 14718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 14818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return product name of the device 14918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 15018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 15118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String getProductName() { 15218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 15318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return Build.PRODUCT; 15418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 15518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 15618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 15718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Retrieves the text from the last UI traversal event received. 15818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 15918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * You can use this method to read the contents in a WebView container 16018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * because the accessibility framework fires events 16118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * as each text is highlighted. You can write a test to perform 16218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * directional arrow presses to focus on different elements inside a WebView, 16318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * and call this method to get the text from each traversed element. 16418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If you are testing a view container that can return a reference to a 16518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Document Object Model (DOM) object, your test should use the view's 16618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * DOM instead. 16718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 16818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return text of the last traversal event, else return an empty string 16918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 17018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 17118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String getLastTraversedText() { 17218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 17318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getQueryController().getLastTraversedText(); 17418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 17518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 17618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 17718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Clears the text from the last UI traversal event. 17818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #getLastTraversedText()}. 17918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 18018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 18118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void clearLastTraversedText() { 18218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 18318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getQueryController().clearLastTraversedText(); 18418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 18518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 18618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 18718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the MENU button. 18818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 18918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 19018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 19118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressMenu() { 19218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 19318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 19418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent( 19518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu KeyEvent.KEYCODE_MENU, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED, 19618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu KEY_PRESS_EVENT_TIMEOUT); 19718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 19818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 19918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 20018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the BACK button. 20118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 20218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 20318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 20418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressBack() { 20518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 20618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 20718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent( 20818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu KeyEvent.KEYCODE_BACK, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED, 20918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu KEY_PRESS_EVENT_TIMEOUT); 21018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 21118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 21218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 21318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the HOME button. 21418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 21518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 21618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 21718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressHome() { 21818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 21918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 22018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().sendKeyAndWaitForEvent( 22118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED, 22218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu KEY_PRESS_EVENT_TIMEOUT); 22318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 22418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 22518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 22618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the SEARCH button. 22718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 22818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 22918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 23018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressSearch() { 23118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 23218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_SEARCH); 23318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 23418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 23518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 23618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the CENTER button. 23718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 23818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 23918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 24018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressDPadCenter() { 24118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 24218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER); 24318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 24418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 24518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 24618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the DOWN button. 24718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 24818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 24918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 25018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressDPadDown() { 25118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 25218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN); 25318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 25418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 25518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 25618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the UP button. 25718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 25818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 25918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 26018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressDPadUp() { 26118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 26218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_DPAD_UP); 26318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 26418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 26518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 26618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the LEFT button. 26718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 26818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 26918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 27018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressDPadLeft() { 27118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 27218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT); 27318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 27418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 27518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 27618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the RIGHT button. 27718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 27818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 27918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 28018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressDPadRight() { 28118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 28218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT); 28318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 28418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 28518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 28618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the DELETE key. 28718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 28818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 28918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 29018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressDelete() { 29118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 29218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_DEL); 29318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 29418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 29518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 29618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the ENTER key. 29718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 29818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 29918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 30018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressEnter() { 30118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 30218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return pressKeyCode(KeyEvent.KEYCODE_ENTER); 30318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 30418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 30518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 30618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press using a key code. 30718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 30818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link KeyEvent} 30918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 31018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 31118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 31218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressKeyCode(int keyCode) { 31318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(keyCode); 31418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 31518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().sendKey(keyCode, 0); 31618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 31718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 31818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 31918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press using a key code. 32018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 32118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link KeyEvent}. 32218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param keyCode the key code of the event. 32318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param metaState an integer in which each bit set to 1 represents a pressed meta key 32418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 32518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 32618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 32718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressKeyCode(int keyCode, int metaState) { 32818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(keyCode, metaState); 32918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 33018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().sendKey(keyCode, metaState); 33118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 33218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 33318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 33418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates a short press on the Recent Apps button. 33518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 33618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 33718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 33818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 33918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 34018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean pressRecentApps() throws RemoteException { 34118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 34218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 34318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().toggleRecentApps(); 34418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 34518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 34618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 34718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Opens the notification shade. 34818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 34918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 35018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 35118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 35218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean openNotification() { 35318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 35418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 35518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().openNotification(); 35618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 35718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 35818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 35918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Opens the Quick Settings shade. 36018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 36118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if successful, else return false 36218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 36318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 36418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean openQuickSettings() { 36518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 36618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 36718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().openQuickSettings(); 36818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 36918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 37018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 37118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Gets the width of the display, in pixels. The width and height details 37218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * are reported based on the current orientation of the display. 37318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return width in pixels or zero on failure 37418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 37518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 37618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public int getDisplayWidth() { 37718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 37818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Display display = getAutomatorBridge().getDefaultDisplay(); 37918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Point p = new Point(); 38018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu display.getSize(p); 38118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return p.x; 38218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 38318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 38418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 38518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Gets the height of the display, in pixels. The size is adjusted based 38618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * on the current orientation of the display. 38718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return height in pixels or zero on failure 38818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 38918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 39018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public int getDisplayHeight() { 39118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 39218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Display display = getAutomatorBridge().getDefaultDisplay(); 39318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Point p = new Point(); 39418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu display.getSize(p); 39518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return p.y; 39618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 39718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 39818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 39918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Perform a click at arbitrary coordinates specified by the user 40018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 40118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param x coordinate 40218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param y coordinate 40318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if the click succeeded else false 40418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 40518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 40618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean click(int x, int y) { 40718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(x, y); 40818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (x >= getDisplayWidth() || y >= getDisplayHeight()) { 40918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return (false); 41018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 41118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().clickNoSync(x, y); 41218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 41318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 41418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 41518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Performs a swipe from one coordinate to another using the number of steps 41618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * to determine smoothness and speed. Each step execution is throttled to 5ms 41718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * per step. So for a 100 steps, the swipe will take about 1/2 second to complete. 41818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 41918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param startX 42018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param startY 42118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param endX 42218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param endY 42318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param steps is the number of move steps sent to the system 42418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return false if the operation fails or the coordinates are invalid 42518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 42618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 42718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean swipe(int startX, int startY, int endX, int endY, int steps) { 42818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(startX, startY, endX, endY, steps); 42918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController() 43018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu .swipe(startX, startY, endX, endY, steps); 43118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 43218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 43318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 43418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Performs a swipe from one coordinate to another coordinate. You can control 43518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the smoothness and speed of the swipe by specifying the number of steps. 43618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Each step execution is throttled to 5 milliseconds per step, so for a 100 43718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * steps, the swipe will take around 0.5 seconds to complete. 43818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 43918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param startX X-axis value for the starting coordinate 44018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param startY Y-axis value for the starting coordinate 44118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param endX X-axis value for the ending coordinate 44218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param endY Y-axis value for the ending coordinate 44318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param steps is the number of steps for the swipe action 44418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if swipe is performed, false if the operation fails 44518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * or the coordinates are invalid 44618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 18 44718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 44818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean drag(int startX, int startY, int endX, int endY, int steps) { 44918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(startX, startY, endX, endY, steps); 45018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController() 45118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu .swipe(startX, startY, endX, endY, steps, true); 45218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 45318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 45418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 45518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Performs a swipe between points in the Point array. Each step execution is throttled 45618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * to 5ms per step. So for a 100 steps, the swipe will take about 1/2 second to complete 45718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 45818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param segments is Point array containing at least one Point object 45918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param segmentSteps steps to inject between two Points 46018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true on success 46118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 46218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 46318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean swipe(Point[] segments, int segmentSteps) { 46418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(segments, segmentSteps); 46518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().swipe(segments, segmentSteps); 46618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 46718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 46818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 46918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Waits for the current application to idle. 47018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Default wait timeout is 10 seconds 47118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 47218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 47318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void waitForIdle() { 47418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 47518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(Configurator.getInstance().getWaitForIdleTimeout()); 47618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 47718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 47818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 47918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Waits for the current application to idle. 48018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param timeout in milliseconds 48118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 48218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 48318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void waitForIdle(long timeout) { 48418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(timeout); 48518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().waitForIdle(timeout); 48618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 48718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 48818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 48918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Retrieves the last activity to report accessibility events. 49018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @deprecated The results returned should be considered unreliable 49118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return String name of activity 49218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 49318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 49418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Deprecated 49518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String getCurrentActivityName() { 49618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 49718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getQueryController().getCurrentActivityName(); 49818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 49918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 50018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 50118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Retrieves the name of the last package to report accessibility events. 50218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return String name of package 50318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 50418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 50518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public String getCurrentPackageName() { 50618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 50718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getQueryController().getCurrentPackageName(); 50818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 50918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 51018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 51118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Registers a {@link UiWatcher} to run automatically when the testing framework is unable to 51218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * find a match using a {@link UiSelector}. See {@link #runWatchers()} 51318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 51418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param name to register the UiWatcher 51518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param watcher {@link UiWatcher} 51618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 51718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 51818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void registerWatcher(String name, UiWatcher watcher) { 51918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(name, watcher); 52018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mInWatcherContext) { 52118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu throw new IllegalStateException("Cannot register new watcher from within another"); 52218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 52318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mWatchers.put(name, watcher); 52418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 52518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 52618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 52718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Removes a previously registered {@link UiWatcher}. 52818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 52918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #registerWatcher(String, UiWatcher)} 53018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param name used to register the UiWatcher 53118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 53218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 53318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void removeWatcher(String name) { 53418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(name); 53518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mInWatcherContext) { 53618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu throw new IllegalStateException("Cannot remove a watcher from within another"); 53718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 53818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mWatchers.remove(name); 53918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 54018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 54118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 54218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * This method forces all registered watchers to run. 54318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #registerWatcher(String, UiWatcher)} 54418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 54518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 54618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void runWatchers() { 54718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 54818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (mInWatcherContext) { 54918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return; 55018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 55118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 55218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu for (String watcherName : mWatchers.keySet()) { 55318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu UiWatcher watcher = mWatchers.get(watcherName); 55418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (watcher != null) { 55518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 55618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mInWatcherContext = true; 55718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (watcher.checkForCondition()) { 55818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu setWatcherTriggered(watcherName); 55918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 56018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (Exception e) { 56118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Log.e(LOG_TAG, "Exceuting watcher: " + watcherName, e); 56218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } finally { 56318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mInWatcherContext = false; 56418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 56518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 56618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 56718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 56818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 56918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 57018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Resets a {@link UiWatcher} that has been triggered. 57118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If a UiWatcher runs and its {@link UiWatcher#checkForCondition()} call 57218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * returned <code>true</code>, then the UiWatcher is considered triggered. 57318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #registerWatcher(String, UiWatcher)} 57418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 57518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 57618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void resetWatcherTriggers() { 57718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 57818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mWatchersTriggers.clear(); 57918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 58018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 58118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 58218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Checks if a specific registered {@link UiWatcher} has triggered. 58318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #registerWatcher(String, UiWatcher)}. If a UiWatcher runs and its 58418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * {@link UiWatcher#checkForCondition()} call returned <code>true</code>, then 58518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * the UiWatcher is considered triggered. This is helpful if a watcher is detecting errors 58618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * from ANR or crash dialogs and the test needs to know if a UiWatcher has been triggered. 58718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 58818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param watcherName 58918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if triggered else false 59018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 59118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 59218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean hasWatcherTriggered(String watcherName) { 59318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(watcherName); 59418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return mWatchersTriggers.contains(watcherName); 59518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 59618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 59718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 59818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Checks if any registered {@link UiWatcher} have triggered. 59918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 60018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #registerWatcher(String, UiWatcher)} 60118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * See {@link #hasWatcherTriggered(String)} 60218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 60318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 60418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean hasAnyWatcherTriggered() { 60518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 60618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return mWatchersTriggers.size() > 0; 60718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 60818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 60918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 61018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Used internally by this class to set a {@link UiWatcher} state as triggered. 61118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param watcherName 61218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 61318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu private void setWatcherTriggered(String watcherName) { 61418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(watcherName); 61518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (!hasWatcherTriggered(watcherName)) { 61618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu mWatchersTriggers.add(watcherName); 61718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 61818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 61918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 62018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 62118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Check if the device is in its natural orientation. This is determined by checking if the 62218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * orientation is at 0 or 180 degrees. 62318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if it is in natural orientation 62418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 62518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 62618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean isNaturalOrientation() { 62718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 62818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 62918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu int ret = getAutomatorBridge().getRotation(); 63018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return ret == UiAutomation.ROTATION_FREEZE_0 || 63118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu ret == UiAutomation.ROTATION_FREEZE_180; 63218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 63318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 63418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 63518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Returns the current rotation of the display, as defined in {@link Surface} 63618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 63718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 63818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public int getDisplayRotation() { 63918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 64018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); 64118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getRotation(); 64218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 64318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 64418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 64518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Disables the sensors and freezes the device rotation at its 64618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * current rotation state. 64718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 64818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 64918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 65018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void freezeRotation() throws RemoteException { 65118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 65218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getInteractionController().freezeRotation(); 65318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 65418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 65518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 65618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Re-enables the sensors and un-freezes the device rotation allowing its contents 65718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * to rotate with the device physical rotation. During a test execution, it is best to 65818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * keep the device frozen in a specific orientation until the test case execution has completed. 65918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 66018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 66118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void unfreezeRotation() throws RemoteException { 66218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 66318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getInteractionController().unfreezeRotation(); 66418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 66518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 66618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 66718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates orienting the device to the left and also freezes rotation 66818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by disabling the sensors. 66918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 67018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If you want to un-freeze the rotation and re-enable the sensors 67118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * see {@link #unfreezeRotation()}. 67218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 67318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 67418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 67518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void setOrientationLeft() throws RemoteException { 67618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 67718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getInteractionController().setRotationLeft(); 67818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit 67918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 68018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 68118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 68218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates orienting the device to the right and also freezes rotation 68318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by disabling the sensors. 68418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 68518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If you want to un-freeze the rotation and re-enable the sensors 68618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * see {@link #unfreezeRotation()}. 68718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 68818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 68918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 69018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void setOrientationRight() throws RemoteException { 69118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 69218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getInteractionController().setRotationRight(); 69318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit 69418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 69518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 69618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 69718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Simulates orienting the device into its natural orientation and also freezes rotation 69818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * by disabling the sensors. 69918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 70018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If you want to un-freeze the rotation and re-enable the sensors 70118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * see {@link #unfreezeRotation()}. 70218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 70318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 70418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 70518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void setOrientationNatural() throws RemoteException { 70618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 70718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getInteractionController().setRotationNatural(); 70818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit 70918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 71018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 71118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 71218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * This method simulates pressing the power button if the screen is OFF else 71318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * it does nothing if the screen is already ON. 71418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 71518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If the screen was OFF and it just got turned ON, this method will insert a 500ms delay 71618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * to allow the device time to wake up and accept input. 71718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 71818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 71918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 72018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void wakeUp() throws RemoteException { 72118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 72218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if(getAutomatorBridge().getInteractionController().wakeDevice()) { 72318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // sync delay to allow the window manager to start accepting input 72418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu // after the device is awakened. 72518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu SystemClock.sleep(500); 72618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 72718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 72818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 72918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 73018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Checks the power manager if the screen is ON. 73118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 73218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if the screen is ON else false 73318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 73418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 73518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 73618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean isScreenOn() throws RemoteException { 73718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 73818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().getInteractionController().isScreenOn(); 73918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 74018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 74118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 74218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * This method simply presses the power button if the screen is ON else 74318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * it does nothing if the screen is already OFF. 74418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 74518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @throws RemoteException 74618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 74718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 74818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void sleep() throws RemoteException { 74918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(); 75018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getInteractionController().sleepDevice(); 75118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 75218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 75318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 75418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Helper method used for debugging to dump the current window's layout hierarchy. 75518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The file root location is /data/local/tmp 75618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 75718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param fileName 75818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 75918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 76018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void dumpWindowHierarchy(String fileName) { 76118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(fileName); 76218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu AccessibilityNodeInfo root = 76318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().getQueryController().getAccessibilityRootNode(); 76418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if(root != null) { 76518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Display display = getAutomatorBridge().getDefaultDisplay(); 76618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Point size = new Point(); 76718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu display.getSize(size); 76818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu AccessibilityNodeInfoDumper.dumpWindowToFile(root, 76918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName), 77018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu display.getRotation(), size.x, size.y); 77118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 77218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 77318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 77418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 77518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Waits for a window content update event to occur. 77618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 77718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If a package name for the window is specified, but the current window 77818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * does not have the same package name, the function returns immediately. 77918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 78018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param packageName the specified window package name (can be <code>null</code>). 78118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * If <code>null</code>, a window update from any front-end window will end the wait 78218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param timeout the timeout for the wait 78318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 78418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if a window update occurred, false if timeout has elapsed or if the current 78518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * window does not have the specified package name 78618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 16 78718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 78818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean waitForWindowUpdate(final String packageName, long timeout) { 78918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(packageName, timeout); 79018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (packageName != null) { 79118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (!packageName.equals(getCurrentPackageName())) { 79218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 79318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 79418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 79518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Runnable emptyRunnable = new Runnable() { 79618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 79718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public void run() { 79818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 79918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu }; 80018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu AccessibilityEventFilter checkWindowUpdate = new AccessibilityEventFilter() { 80118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu @Override 80218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean accept(AccessibilityEvent t) { 80318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu if (t.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { 80418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return packageName == null || packageName.equals(t.getPackageName()); 80518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 80618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 80718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 80818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu }; 80918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu try { 81018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu getAutomatorBridge().executeCommandAndWaitForAccessibilityEvent( 81118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu emptyRunnable, checkWindowUpdate, timeout); 81218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (TimeoutException e) { 81318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 81418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } catch (Exception e) { 81518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Log.e(LOG_TAG, "waitForWindowUpdate: general exception from bridge", e); 81618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return false; 81718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 81818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return true; 81918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 82018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 82118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 82218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Take a screenshot of current window and store it as PNG 82318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 82418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Default scale of 1.0f (original size) and 90% quality is used 82518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The screenshot is adjusted per screen rotation 82618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 82718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param storePath where the PNG should be written to 82818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if screen shot is created successfully, false otherwise 82918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 83018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 83118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean takeScreenshot(File storePath) { 83218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(storePath); 83318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return takeScreenshot(storePath, 1.0f, 90); 83418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 83518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu 83618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu /** 83718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * Take a screenshot of current window and store it as PNG 83818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 83918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * The screenshot is adjusted per screen rotation 84018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * 84118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param storePath where the PNG should be written to 84218b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param scale scale the screenshot down if needed; 1.0f for original size 84318b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @param quality quality of the PNG compression; range: 0-100 84418b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @return true if screen shot is created successfully, false otherwise 84518b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu * @since API Level 17 84618b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu */ 84718b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu public boolean takeScreenshot(File storePath, float scale, int quality) { 84818b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu Tracer.trace(storePath, scale, quality); 84918b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu return getAutomatorBridge().takeScreenshot(storePath, quality); 85018b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu } 85118b892c723e812a7e111f102d2b0c0782b116bb6Guang Zhu} 852