1/* 2 * Copyright (C) 2015 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 */ 16package com.android.tv.testing.uihelper; 17 18import static junit.framework.Assert.assertTrue; 19 20import android.app.Instrumentation; 21import android.app.UiAutomation; 22import android.os.Build; 23import android.os.SystemClock; 24import android.support.test.uiautomator.Configurator; 25import android.support.test.uiautomator.Direction; 26import android.support.test.uiautomator.UiDevice; 27import android.view.InputDevice; 28import android.view.KeyEvent; 29 30/** 31 * Static utility methods for {@link UiDevice}. 32 */ 33public final class UiDeviceUtils { 34 35 public static void pressDpad(UiDevice uiDevice, Direction direction) { 36 switch (direction) { 37 case UP: 38 uiDevice.pressDPadUp(); 39 break; 40 case DOWN: 41 uiDevice.pressDPadDown(); 42 break; 43 case LEFT: 44 uiDevice.pressDPadLeft(); 45 break; 46 case RIGHT: 47 uiDevice.pressDPadRight(); 48 break; 49 default: 50 throw new IllegalArgumentException(direction.toString()); 51 } 52 } 53 54 55 public static void pressKeys(UiDevice uiDevice, int... keyCodes) { 56 for (int k : keyCodes) { 57 uiDevice.pressKeyCode(k); 58 } 59 } 60 61 /** 62 * Parses the string and sends the corresponding individual key presses. 63 * <p> 64 * <b>Note:</b> only handles 0-9, '.', and '-'. 65 */ 66 public static void pressKeys(UiDevice uiDevice, String keys) { 67 for (char c : keys.toCharArray()) { 68 if (c >= '0' && c <= '9') { 69 uiDevice.pressKeyCode(KeyEvent.KEYCODE_0 + c - '0'); 70 } else if (c == '-') { 71 uiDevice.pressKeyCode(KeyEvent.KEYCODE_MINUS); 72 } else if (c == '.') { 73 uiDevice.pressKeyCode(KeyEvent.KEYCODE_PERIOD); 74 } else { 75 throw new IllegalArgumentException(c + " is not supported"); 76 } 77 } 78 } 79 80 /** 81 * Sends the DPAD Center key presses with the {@code repeat} count. 82 * TODO: Remove instrumentation argument once migrated to JUnit4. 83 */ 84 public static void pressDPadCenter(Instrumentation instrumentation, int repeat) { 85 pressKey(instrumentation, KeyEvent.KEYCODE_DPAD_CENTER, repeat); 86 } 87 88 private static void pressKey(Instrumentation instrumentation, int keyCode, int repeat) { 89 UiDevice.getInstance(instrumentation).waitForIdle(); 90 for (int i = 0; i < repeat; ++i) { 91 assertPressKeyDown(instrumentation, keyCode, false); 92 if (i < repeat - 1) { 93 assertPressKeyUp(instrumentation, keyCode, false); 94 } 95 } 96 // Send last key event synchronously. 97 assertPressKeyUp(instrumentation, keyCode, true); 98 } 99 100 private static void assertPressKeyDown(Instrumentation instrumentation, int keyCode, 101 boolean sync) { 102 assertPressKey(instrumentation, KeyEvent.ACTION_DOWN, keyCode, sync); 103 } 104 105 private static void assertPressKeyUp(Instrumentation instrumentation, int keyCode, 106 boolean sync) { 107 assertPressKey(instrumentation, KeyEvent.ACTION_UP, keyCode, sync); 108 } 109 110 private static void assertPressKey(Instrumentation instrumentation, int action, int keyCode, 111 boolean sync) { 112 long eventTime = SystemClock.uptimeMillis(); 113 KeyEvent event = new KeyEvent(eventTime, eventTime, action, keyCode, 0, 0, -1, 0, 0, 114 InputDevice.SOURCE_KEYBOARD); 115 assertTrue("Failed to inject key up event:" + event, 116 injectEvent(instrumentation, event, sync)); 117 } 118 119 private static boolean injectEvent(Instrumentation instrumentation, KeyEvent event, 120 boolean sync) { 121 return getUiAutomation(instrumentation).injectInputEvent(event, sync); 122 } 123 124 private static UiAutomation getUiAutomation(Instrumentation instrumentation) { 125 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 126 int flags = Configurator.getInstance().getUiAutomationFlags(); 127 return instrumentation.getUiAutomation(flags); 128 } else { 129 return instrumentation.getUiAutomation(); 130 } 131 } 132 133 private UiDeviceUtils() { 134 } 135} 136