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.util.Log; 34 import android.view.KeyEvent; 35 36 import androidx.test.uiautomator.UiDevice; 37 38 import java.util.function.BooleanSupplier; 39 40 /** 41 * Helper class to interact with {@link UiDevice}. 42 * 43 * All references to {@link UiDevice} and {@link KeyEvent} should be here for easy debugging. 44 */ 45 public class UiDeviceUtils { 46 47 private static final String TAG = "UiDeviceUtils"; 48 private static final boolean DEBUG = false; 49 waitForDeviceIdle(long timeout)50 static void waitForDeviceIdle(long timeout) { 51 if (DEBUG) Log.d(TAG, "waitForDeviceIdle: timeout=" + timeout); 52 getDevice().waitForIdle(timeout); 53 } 54 wakeUpDevice()55 public static void wakeUpDevice() throws RemoteException { 56 if (DEBUG) Log.d(TAG, "wakeUpDevice"); 57 getDevice().wakeUp(); 58 } 59 dragPointer(Point from, Point to, int steps)60 public static void dragPointer(Point from, Point to, int steps) { 61 if (DEBUG) Log.d(TAG, "dragPointer: from=" + from + " to=" + to + " steps=" + steps); 62 getDevice().drag(from.x, from.y, to.x, to.y, steps); 63 } 64 pressEnterButton()65 static void pressEnterButton() { 66 if (DEBUG) Log.d(TAG, "pressEnterButton"); 67 getDevice().pressEnter(); 68 } 69 70 /** 71 * Simulates a pressed event of {@link KeyEvent#KEYCODE_HOME}. Note this will stop app switches 72 * for 5s (see android.permission.STOP_APP_SWITCHES). 73 */ pressHomeButton()74 public static void pressHomeButton() { 75 if (DEBUG) Log.d(TAG, "pressHomeButton"); 76 getDevice().pressHome(); 77 } 78 pressBackButton()79 public static void pressBackButton() { 80 if (DEBUG) Log.d(TAG, "pressBackButton"); 81 getDevice().pressBack(); 82 } 83 pressMenuButton()84 public static void pressMenuButton() { 85 if (DEBUG) Log.d(TAG, "pressMenuButton"); 86 getDevice().pressMenu(); 87 } 88 pressSleepButton()89 public static void pressSleepButton() { 90 if (DEBUG) Log.d(TAG, "pressSleepButton"); 91 final PowerManager pm = getInstrumentation() 92 .getContext().getSystemService(PowerManager.class); 93 retryPressKeyCode(KEYCODE_SLEEP, () -> pm != null && !pm.isInteractive(), 94 "***Waiting for device sleep..."); 95 } 96 pressWakeupButton()97 public static void pressWakeupButton() { 98 if (DEBUG) Log.d(TAG, "pressWakeupButton"); 99 final PowerManager pm = getInstrumentation() 100 .getContext().getSystemService(PowerManager.class); 101 retryPressKeyCode(KEYCODE_WAKEUP, () -> pm != null && pm.isInteractive(), 102 "***Waiting for device wakeup..."); 103 } 104 pressUnlockButton()105 public static void pressUnlockButton() { 106 if (DEBUG) Log.d(TAG, "pressUnlockButton"); 107 final KeyguardManager kgm = getInstrumentation() 108 .getContext().getSystemService(KeyguardManager.class); 109 retryPressKeyCode(KEYCODE_MENU, () -> kgm != null && !kgm.isKeyguardLocked(), 110 "***Waiting for device unlock..."); 111 } 112 pressWindowButton()113 static void pressWindowButton() { 114 if (DEBUG) Log.d(TAG, "pressWindowButton"); 115 pressKeyCode(KEYCODE_WINDOW); 116 } 117 pressAppSwitchButton()118 static void pressAppSwitchButton() { 119 if (DEBUG) Log.d(TAG, "pressAppSwitchButton"); 120 pressKeyCode(KEYCODE_APP_SWITCH); 121 } 122 retryPressKeyCode(int keyCode, BooleanSupplier waitFor, String msg)123 private static void retryPressKeyCode(int keyCode, BooleanSupplier waitFor, String msg) { 124 int retry = 1; 125 do { 126 pressKeyCode(keyCode); 127 if (waitFor.getAsBoolean()) { 128 return; 129 } 130 Log.d(TAG, msg + " retry=" + retry); 131 SystemClock.sleep(50); 132 } while (retry++ < 5); 133 if (!waitFor.getAsBoolean()) { 134 logE(msg + " FAILED"); 135 } 136 } 137 pressKeyCode(int keyCode)138 private static void pressKeyCode(int keyCode) { 139 getDevice().pressKeyCode(keyCode); 140 } 141 getDevice()142 private static UiDevice getDevice() { 143 return UiDevice.getInstance(getInstrumentation()); 144 } 145 } 146