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.view; 18 19 import static android.view.Display.INVALID_DISPLAY; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 24 import android.os.Parcel; 25 26 import androidx.test.ext.junit.runners.AndroidJUnit4; 27 import androidx.test.filters.SmallTest; 28 29 import org.junit.Test; 30 import org.junit.runner.RunWith; 31 32 import java.util.HashSet; 33 import java.util.Set; 34 35 @SmallTest 36 @RunWith(AndroidJUnit4.class) 37 public class KeyEventTest { 38 39 private static final int ID = 0xabcdef; 40 private static final int DOWN_TIME = 50; 41 private static final long EVENT_TIME = 100; 42 private static final int ACTION = KeyEvent.ACTION_DOWN; 43 private static final int KEYCODE = KeyEvent.KEYCODE_0; 44 private static final int REPEAT = 0; 45 private static final int METASTATE = 0; 46 private static final int DEVICE_ID = 0; 47 private static final int SCAN_CODE = 0; 48 private static final int FLAGS = 0; 49 private static final int SOURCE = InputDevice.SOURCE_KEYBOARD; 50 private static final byte[] HMAC = null; 51 private static final String CHARACTERS = null; 52 53 private static final int ID_SOURCE_MASK = 0x3 << 30; 54 55 @Test testObtain()56 public void testObtain() { 57 KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, 58 METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, CHARACTERS); 59 assertEquals(DOWN_TIME, keyEvent.getDownTime()); 60 assertEquals(EVENT_TIME, keyEvent.getEventTime()); 61 assertEquals(ACTION, keyEvent.getAction()); 62 assertEquals(KEYCODE, keyEvent.getKeyCode()); 63 assertEquals(REPEAT, keyEvent.getRepeatCount()); 64 assertEquals(METASTATE, keyEvent.getMetaState()); 65 assertEquals(DEVICE_ID, keyEvent.getDeviceId()); 66 assertEquals(SCAN_CODE, keyEvent.getScanCode()); 67 assertEquals(FLAGS, keyEvent.getFlags()); 68 assertEquals(SOURCE, keyEvent.getSource()); 69 assertEquals(INVALID_DISPLAY, keyEvent.getDisplayId()); 70 assertEquals(CHARACTERS, keyEvent.getCharacters()); 71 } 72 73 @Test testObtainFromKeyEvent()74 public void testObtainFromKeyEvent() { 75 KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, 76 METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, CHARACTERS); 77 KeyEvent keyEvent2 = KeyEvent.obtain(keyEvent); 78 compareKeys(keyEvent, keyEvent2); 79 } 80 81 @Test testObtainWithDisplayId()82 public void testObtainWithDisplayId() { 83 final int displayId = 5; 84 KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, 85 METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, displayId, CHARACTERS); 86 assertEquals(DOWN_TIME, keyEvent.getDownTime()); 87 assertEquals(EVENT_TIME, keyEvent.getEventTime()); 88 assertEquals(ACTION, keyEvent.getAction()); 89 assertEquals(KEYCODE, keyEvent.getKeyCode()); 90 assertEquals(REPEAT, keyEvent.getRepeatCount()); 91 assertEquals(METASTATE, keyEvent.getMetaState()); 92 assertEquals(DEVICE_ID, keyEvent.getDeviceId()); 93 assertEquals(SCAN_CODE, keyEvent.getScanCode()); 94 assertEquals(FLAGS, keyEvent.getFlags()); 95 assertEquals(SOURCE, keyEvent.getSource()); 96 assertEquals(displayId, keyEvent.getDisplayId()); 97 assertEquals(CHARACTERS, keyEvent.getCharacters()); 98 } 99 100 /** 101 * Tests that it can generate 500 consecutive distinct numbers. This is a non-deterministic test 102 * but with 30 bits randomness the failure rate is roughly 4.52e-5, which is negligible enough. 103 * Probability formula: N * (N - 1) * ... * (N - n + 1) / N^n, where N = 2^30 and n = 500 for 104 * this test. 105 */ 106 @Test testObtainGeneratesUniqueId()107 public void testObtainGeneratesUniqueId() { 108 Set<Integer> set = new HashSet<>(); 109 for (int i = 0; i < 500; ++i) { 110 KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, 111 METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, CHARACTERS); 112 assertFalse("Found duplicate ID in round " + i, 113 set.contains(keyEvent.getId())); 114 set.add(keyEvent.getSequenceNumber()); 115 } 116 } 117 118 @Test testConstructorGeneratesUniqueId()119 public void testConstructorGeneratesUniqueId() { 120 Set<Integer> set = new HashSet<>(); 121 for (int i = 0; i < 500; ++i) { 122 KeyEvent keyEvent = new KeyEvent(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT); 123 assertFalse("Found duplicate sequence number in round " + i, 124 set.contains(keyEvent.getId())); 125 set.add(keyEvent.getSequenceNumber()); 126 } 127 } 128 129 @Test testObtainGeneratesIdWithRightSource()130 public void testObtainGeneratesIdWithRightSource() { 131 for (int i = 0; i < 500; ++i) { 132 KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, 133 METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, CHARACTERS); 134 assertEquals(0x3 << 30, ID_SOURCE_MASK & keyEvent.getId()); 135 } 136 } 137 138 @Test testConstructorGeneratesIdWithRightSource()139 public void testConstructorGeneratesIdWithRightSource() { 140 for (int i = 0; i < 500; ++i) { 141 KeyEvent keyEvent = new KeyEvent(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT); 142 assertEquals(0x3 << 30, ID_SOURCE_MASK & keyEvent.getId()); 143 } 144 } 145 146 @Test testParcelUnparcel()147 public void testParcelUnparcel() { 148 KeyEvent key1 = createKey(); 149 Parcel parcel = Parcel.obtain(); 150 key1.writeToParcel(parcel, 0 /*flags*/); 151 parcel.setDataPosition(0); 152 153 KeyEvent key2 = KeyEvent.CREATOR.createFromParcel(parcel); 154 parcel.recycle(); 155 156 compareKeys(key1, key2); 157 } 158 159 @Test testConstructor()160 public void testConstructor() { 161 KeyEvent key1 = createKey(); 162 KeyEvent key2 = new KeyEvent(key1); 163 compareKeys(key1, key2); 164 } 165 createKey()166 private static KeyEvent createKey() { 167 return KeyEvent.obtain(ID, DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, METASTATE, 168 DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, INVALID_DISPLAY, HMAC, CHARACTERS); 169 } 170 compareKeys(KeyEvent key1, KeyEvent key2)171 private static void compareKeys(KeyEvent key1, KeyEvent key2) { 172 assertEquals(key1.getId(), key2.getId()); 173 assertEquals(key1.getDownTime(), key2.getDownTime()); 174 assertEquals(key1.getEventTime(), key2.getEventTime()); 175 assertEquals(key1.getAction(), key2.getAction()); 176 assertEquals(key1.getKeyCode(), key2.getKeyCode()); 177 assertEquals(key1.getRepeatCount(), key2.getRepeatCount()); 178 assertEquals(key1.getMetaState(), key2.getMetaState()); 179 assertEquals(key1.getDeviceId(), key2.getDeviceId()); 180 assertEquals(key1.getScanCode(), key2.getScanCode()); 181 assertEquals(key1.getFlags(), key2.getFlags()); 182 assertEquals(key1.getSource(), key2.getSource()); 183 assertEquals(key1.getDisplayId(), key2.getDisplayId()); 184 assertEquals(key1.getCharacters(), key2.getCharacters()); 185 } 186 } 187