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