1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.server.wm; 18 19 import static android.server.wm.StateLogger.logE; 20 import static android.view.KeyEvent.KEYCODE_APP_SWITCH; 21 import static android.view.KeyEvent.KEYCODE_MENU; 22 import static android.view.KeyEvent.KEYCODE_SLEEP; 23 import static android.view.KeyEvent.KEYCODE_WAKEUP; 24 import static android.view.KeyEvent.KEYCODE_WINDOW; 25 26 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 27 28 import android.app.KeyguardManager; 29 import android.graphics.Point; 30 import android.os.PowerManager; 31 import android.os.RemoteException; 32 import android.os.SystemClock; 33 import android.support.test.uiautomator.UiDevice; 34 import android.util.Log; 35 import android.view.KeyEvent; 36 37 import java.util.function.BooleanSupplier; 38 39 /** 40 * Helper class to interact with {@link UiDevice}. 41 * 42 * All references to {@link UiDevice} and {@link KeyEvent} should be here for easy debugging. 43 */ 44 public class UiDeviceUtils { 45 46 private static final String TAG = "UiDeviceUtils"; 47 private static final boolean DEBUG = false; 48 waitForDeviceIdle(long timeout)49 static void waitForDeviceIdle(long timeout) { 50 if (DEBUG) Log.d(TAG, "waitForDeviceIdle: timeout=" + timeout); 51 getDevice().waitForIdle(timeout); 52 } 53 wakeUpDevice()54 public static void wakeUpDevice() throws RemoteException { 55 if (DEBUG) Log.d(TAG, "wakeUpDevice"); 56 getDevice().wakeUp(); 57 } 58 dragPointer(Point from, Point to, int steps)59 public static void dragPointer(Point from, Point to, int steps) { 60 if (DEBUG) Log.d(TAG, "dragPointer: from=" + from + " to=" + to + " steps=" + steps); 61 getDevice().drag(from.x, from.y, to.x, to.y, steps); 62 } 63 pressEnterButton()64 static void pressEnterButton() { 65 if (DEBUG) Log.d(TAG, "pressEnterButton"); 66 getDevice().pressEnter(); 67 } 68 69 /** 70 * Simulates a pressed event of {@link KeyEvent#KEYCODE_HOME}. Note this will stop app switches 71 * for 5s (see android.permission.STOP_APP_SWITCHES). 72 */ pressHomeButton()73 public static void pressHomeButton() { 74 if (DEBUG) Log.d(TAG, "pressHomeButton"); 75 getDevice().pressHome(); 76 } 77 pressBackButton()78 public static void pressBackButton() { 79 if (DEBUG) Log.d(TAG, "pressBackButton"); 80 getDevice().pressBack(); 81 } 82 pressMenuButton()83 public static void pressMenuButton() { 84 if (DEBUG) Log.d(TAG, "pressMenuButton"); 85 getDevice().pressMenu(); 86 } 87 pressSleepButton()88 static void pressSleepButton() { 89 if (DEBUG) Log.d(TAG, "pressSleepButton"); 90 final PowerManager pm = getInstrumentation() 91 .getContext().getSystemService(PowerManager.class); 92 retryPressKeyCode(KEYCODE_SLEEP, () -> pm != null && !pm.isInteractive(), 93 "***Waiting for device sleep..."); 94 } 95 pressWakeupButton()96 public static void pressWakeupButton() { 97 if (DEBUG) Log.d(TAG, "pressWakeupButton"); 98 final PowerManager pm = getInstrumentation() 99 .getContext().getSystemService(PowerManager.class); 100 retryPressKeyCode(KEYCODE_WAKEUP, () -> pm != null && pm.isInteractive(), 101 "***Waiting for device wakeup..."); 102 } 103 pressUnlockButton()104 public static void pressUnlockButton() { 105 if (DEBUG) Log.d(TAG, "pressUnlockButton"); 106 final KeyguardManager kgm = getInstrumentation() 107 .getContext().getSystemService(KeyguardManager.class); 108 retryPressKeyCode(KEYCODE_MENU, () -> kgm != null && !kgm.isKeyguardLocked(), 109 "***Waiting for device unlock..."); 110 } 111 pressWindowButton()112 static void pressWindowButton() { 113 if (DEBUG) Log.d(TAG, "pressWindowButton"); 114 pressKeyCode(KEYCODE_WINDOW); 115 } 116 pressAppSwitchButton()117 static void pressAppSwitchButton() { 118 if (DEBUG) Log.d(TAG, "pressAppSwitchButton"); 119 pressKeyCode(KEYCODE_APP_SWITCH); 120 } 121 retryPressKeyCode(int keyCode, BooleanSupplier waitFor, String msg)122 private static void retryPressKeyCode(int keyCode, BooleanSupplier waitFor, String msg) { 123 int retry = 1; 124 do { 125 pressKeyCode(keyCode); 126 if (waitFor.getAsBoolean()) { 127 return; 128 } 129 Log.d(TAG, msg + " retry=" + retry); 130 SystemClock.sleep(50); 131 } while (retry++ < 5); 132 if (!waitFor.getAsBoolean()) { 133 logE(msg + " FAILED"); 134 } 135 } 136 pressKeyCode(int keyCode)137 private static void pressKeyCode(int keyCode) { 138 getDevice().pressKeyCode(keyCode); 139 } 140 getDevice()141 private static UiDevice getDevice() { 142 return UiDevice.getInstance(getInstrumentation()); 143 } 144 } 145