1 /*
2  * Copyright (C) 2008 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.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNotSame;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.mockito.Matchers.any;
26 import static org.mockito.Matchers.anyInt;
27 import static org.mockito.Mockito.doAnswer;
28 import static org.mockito.Mockito.doReturn;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.never;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.verifyNoMoreInteractions;
34 
35 import android.os.Parcel;
36 import android.os.Parcelable;
37 import android.os.SystemClock;
38 import android.platform.test.annotations.AppModeSdkSandbox;
39 import android.text.method.MetaKeyKeyListener;
40 import android.view.InputDevice;
41 import android.view.KeyCharacterMap;
42 import android.view.KeyCharacterMap.KeyData;
43 import android.view.KeyEvent;
44 import android.view.cts.util.NativeHeapLeakDetector;
45 
46 import androidx.test.filters.SmallTest;
47 import androidx.test.runner.AndroidJUnit4;
48 
49 import junit.framework.Assert;
50 
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 import org.mockito.invocation.InvocationOnMock;
55 
56 /**
57  * Test {@link KeyEvent}.
58  */
59 @SmallTest
60 @RunWith(AndroidJUnit4.class)
61 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
62 public class KeyEventTest {
63     private KeyEvent mKeyEvent;
64     private long mDownTime;
65     private long mEventTime;
66 
67     // Underestimated from ~112 B to breach threshold when leaked
68     private static final int APPROX_KEY_EVENT_SIZE_BYTES = 100;
69     private static final int NUM_KEY_EVENT_ALLOCATIONS =
70             NativeHeapLeakDetector.MEMORY_LEAK_THRESHOLD_KB * 1024 / APPROX_KEY_EVENT_SIZE_BYTES;
71 
nativeKeyEventTest(KeyEvent event)72     private static native void nativeKeyEventTest(KeyEvent event);
73 
obtainNativeKeyEventCopyFromJava(KeyEvent event)74     private static native void obtainNativeKeyEventCopyFromJava(KeyEvent event);
75 
obtainKeyEventCopyFromNative(KeyEvent event)76     private static native KeyEvent obtainKeyEventCopyFromNative(KeyEvent event);
77 
78     static {
79         System.loadLibrary("ctsview_jni");
80     }
81 
82     @Before
setup()83     public void setup() {
84         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
85 
86         mDownTime = SystemClock.uptimeMillis();
87         mEventTime = SystemClock.uptimeMillis();
88     }
89 
90     @Test
testConstructor()91     public void testConstructor() {
92         new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
93 
94         new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, 5);
95 
96         new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, 5,
97                 KeyEvent.META_SHIFT_ON);
98 
99         new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, 5,
100                 KeyEvent.META_SHIFT_ON, 1, 1);
101 
102         new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, 5,
103                 KeyEvent.META_SHIFT_ON, 1, 1, KeyEvent.FLAG_SOFT_KEYBOARD);
104 
105         KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
106         new KeyEvent(keyEvent);
107         new KeyEvent(keyEvent, mEventTime, 1);
108 
109         new KeyEvent(mDownTime, "test", 0, KeyEvent.FLAG_SOFT_KEYBOARD);
110     }
111 
112     @Test
testGetCharacters()113     public void testGetCharacters() {
114         String characters = "android_test";
115         mKeyEvent = new KeyEvent(mDownTime, characters, 0, KeyEvent.FLAG_SOFT_KEYBOARD);
116         assertEquals(KeyEvent.ACTION_MULTIPLE, mKeyEvent.getAction());
117         assertEquals(KeyEvent.KEYCODE_UNKNOWN, mKeyEvent.getKeyCode());
118         assertEquals(characters, mKeyEvent.getCharacters());
119 
120         // Make sure mCharacters survives after serialization / deserialization
121         KeyEvent keyEvent = parcelUnparcel(mKeyEvent);
122         assertEquals(mKeyEvent.getCharacters(), keyEvent.getCharacters());
123 
124         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
125         assertNull(mKeyEvent.getCharacters());
126     }
127 
128     @Test
testGetMaxKeyCode()129     public void testGetMaxKeyCode() {
130         assertTrue(KeyEvent.getMaxKeyCode() > 0);
131     }
132 
133     @Test
testMetaKeyStates()134     public void testMetaKeyStates() {
135         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, 5,
136                 KeyEvent.META_ALT_ON);
137         assertTrue(mKeyEvent.isAltPressed());
138         assertFalse(mKeyEvent.isCtrlPressed());
139         assertFalse(mKeyEvent.isFunctionPressed());
140         assertFalse(mKeyEvent.isMetaPressed());
141         assertFalse(mKeyEvent.isShiftPressed());
142         assertFalse(mKeyEvent.isSymPressed());
143 
144         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_1, 4,
145                 KeyEvent.META_CTRL_ON);
146         assertFalse(mKeyEvent.isAltPressed());
147         assertTrue(mKeyEvent.isCtrlPressed());
148         assertFalse(mKeyEvent.isFunctionPressed());
149         assertFalse(mKeyEvent.isMetaPressed());
150         assertFalse(mKeyEvent.isShiftPressed());
151         assertFalse(mKeyEvent.isSymPressed());
152 
153         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_2, 3,
154                 KeyEvent.META_FUNCTION_ON);
155         assertFalse(mKeyEvent.isAltPressed());
156         assertFalse(mKeyEvent.isCtrlPressed());
157         assertTrue(mKeyEvent.isFunctionPressed());
158         assertFalse(mKeyEvent.isMetaPressed());
159         assertFalse(mKeyEvent.isShiftPressed());
160         assertFalse(mKeyEvent.isSymPressed());
161 
162         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_3, 2,
163                 KeyEvent.META_META_ON);
164         assertFalse(mKeyEvent.isAltPressed());
165         assertFalse(mKeyEvent.isCtrlPressed());
166         assertFalse(mKeyEvent.isFunctionPressed());
167         assertTrue(mKeyEvent.isMetaPressed());
168         assertFalse(mKeyEvent.isShiftPressed());
169         assertFalse(mKeyEvent.isSymPressed());
170 
171         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_4, 1,
172                 KeyEvent.META_SHIFT_ON);
173         assertFalse(mKeyEvent.isAltPressed());
174         assertFalse(mKeyEvent.isCtrlPressed());
175         assertFalse(mKeyEvent.isFunctionPressed());
176         assertFalse(mKeyEvent.isMetaPressed());
177         assertTrue(mKeyEvent.isShiftPressed());
178         assertFalse(mKeyEvent.isSymPressed());
179 
180         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_5, 0,
181                 KeyEvent.META_SYM_ON);
182         assertFalse(mKeyEvent.isAltPressed());
183         assertFalse(mKeyEvent.isCtrlPressed());
184         assertFalse(mKeyEvent.isFunctionPressed());
185         assertFalse(mKeyEvent.isMetaPressed());
186         assertFalse(mKeyEvent.isShiftPressed());
187         assertTrue(mKeyEvent.isSymPressed());
188     }
189 
190     @Test
testGetDeadChar()191     public void testGetDeadChar() {
192         // decimal number of è is 232.
193         assertEquals(232, KeyEvent.getDeadChar('`', 'e'));
194     }
195 
196     @Test
testGetKeyData()197     public void testGetKeyData() {
198         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z);
199         KeyData keyData = new KeyData();
200         assertTrue(mKeyEvent.getKeyData(keyData));
201 
202         assertEquals('Z', keyData.displayLabel);
203         assertEquals(0, keyData.number);
204         assertEquals('z', keyData.meta[0]);
205         assertEquals('Z', keyData.meta[1]);
206         assertEquals(0, keyData.meta[3]);
207     }
208 
209     @Test
testDispatch()210     public void testDispatch() {
211         final KeyEvent.Callback callback = mock(KeyEvent.Callback.class);
212         doReturn(true).when(callback).onKeyDown(anyInt(), any(KeyEvent.class));
213         doReturn(true).when(callback).onKeyUp(anyInt(), any(KeyEvent.class));
214         doAnswer((InvocationOnMock invocation) -> {
215             final int count = (Integer) invocation.getArguments()[1];
216             return (count < 1) ? false : true;
217         }).when(callback).onKeyMultiple(anyInt(), anyInt(), any(KeyEvent.class));
218 
219         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
220         verify(callback, never()).onKeyDown(anyInt(), any(KeyEvent.class));
221         assertTrue(mKeyEvent.dispatch(callback));
222         verify(callback, times(1)).onKeyDown(KeyEvent.KEYCODE_0, mKeyEvent);
223         verifyNoMoreInteractions(callback);
224 
225         mKeyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0);
226         verify(callback, never()).onKeyUp(anyInt(), any(KeyEvent.class));
227         assertTrue(mKeyEvent.dispatch(callback));
228         verify(callback, times(1)).onKeyUp(KeyEvent.KEYCODE_0, mKeyEvent);
229         verifyNoMoreInteractions(callback);
230 
231         int count = 2;
232         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_MULTIPLE,
233                 KeyEvent.KEYCODE_0, count);
234         verify(callback, never()).onKeyMultiple(anyInt(), anyInt(), any(KeyEvent.class));
235         assertTrue(mKeyEvent.dispatch(callback));
236         verify(callback, times(1)).onKeyMultiple(KeyEvent.KEYCODE_0, count, mKeyEvent);
237         verifyNoMoreInteractions(callback);
238 
239         count = 0;
240         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_MULTIPLE,
241                 KeyEvent.KEYCODE_0, count);
242         assertTrue(mKeyEvent.dispatch(callback));
243         // Note that even though we didn't reset our mock callback, we have a brand new
244         // instance of KeyEvent in mKeyEvent. This is why we're expecting the relevant
245         // onKeyXXX() methods on the mock callback to be called once with that new KeyEvent
246         // instance.
247         verify(callback, times(1)).onKeyDown(KeyEvent.KEYCODE_0, mKeyEvent);
248         verify(callback, times(1)).onKeyMultiple(KeyEvent.KEYCODE_0, count, mKeyEvent);
249         verify(callback, times(1)).onKeyUp(KeyEvent.KEYCODE_0, mKeyEvent);
250         verifyNoMoreInteractions(callback);
251     }
252 
253     @Test
testGetMetaState()254     public void testGetMetaState() {
255         int metaState = KeyEvent.META_ALT_ON;
256         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_MULTIPLE,
257                 KeyEvent.KEYCODE_1, 1, metaState);
258         assertEquals(metaState, mKeyEvent.getMetaState());
259     }
260 
261     @Test
testGetEventTime()262     public void testGetEventTime() {
263         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
264                 KeyEvent.KEYCODE_0, 5);
265         assertEquals(mEventTime, mKeyEvent.getEventTime());
266     }
267 
268     @Test
testGetDownTime()269     public void testGetDownTime() {
270         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
271                 KeyEvent.KEYCODE_0, 5);
272         assertEquals(mDownTime, mKeyEvent.getDownTime());
273     }
274 
275     @Test
testGetUnicodeChar1()276     public void testGetUnicodeChar1() {
277         // 48 is Unicode character of '0'
278         assertEquals(48, mKeyEvent.getUnicodeChar());
279 
280         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
281                 KeyEvent.KEYCODE_9, 5, 0);
282         // 57 is Unicode character of '9'
283         assertEquals(57, mKeyEvent.getUnicodeChar());
284 
285         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
286                 KeyEvent.KEYCODE_ALT_LEFT, 5, KeyEvent.META_SHIFT_ON);
287         // 'ALT' key is not a type Unicode character.
288         assertEquals(0, mKeyEvent.getUnicodeChar());
289     }
290 
291     @Test
testGetUnicodeChar2()292     public void testGetUnicodeChar2() {
293         // 48 is Unicode character of '0'
294         assertEquals(48, mKeyEvent.getUnicodeChar(MetaKeyKeyListener.META_CAP_LOCKED));
295         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
296                 KeyEvent.KEYCODE_9, 5, 0);
297 
298         // 57 is Unicode character of '9'
299         assertEquals(57, mKeyEvent.getUnicodeChar(0));
300 
301         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
302                 KeyEvent.KEYCODE_ALT_LEFT, 5, KeyEvent.META_SHIFT_ON);
303         // 'ALT' key is not a type Unicode character.
304         assertEquals(0, mKeyEvent.getUnicodeChar(0));
305     }
306 
307     @Test
testGetNumber()308     public void testGetNumber() {
309         // 48 is associated with key '0'
310         assertEquals(48, mKeyEvent.getNumber());
311 
312         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_3);
313         // 51 is associated with key '3'
314         assertEquals(51, mKeyEvent.getNumber());
315     }
316 
317     @Test
testGetDeviceId()318     public void testGetDeviceId() {
319         int deviceId = 1;
320         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, 5,
321                 KeyEvent.META_SHIFT_ON, deviceId, 1);
322         assertEquals(deviceId, mKeyEvent.getDeviceId());
323     }
324 
325     @SuppressWarnings("ReturnValueIgnored")
326     @Test
testToString()327     public void testToString() {
328         // make sure it does not throw any exception.
329         mKeyEvent.toString();
330     }
331 
332     @Test
testGetModifierMetaStateMask()333     public void testGetModifierMetaStateMask() {
334         int mask = KeyEvent.getModifierMetaStateMask();
335         assertTrue((mask & KeyEvent.META_SHIFT_ON) != 0);
336         assertTrue((mask & KeyEvent.META_SHIFT_LEFT_ON) != 0);
337         assertTrue((mask & KeyEvent.META_SHIFT_RIGHT_ON) != 0);
338         assertTrue((mask & KeyEvent.META_ALT_ON) != 0);
339         assertTrue((mask & KeyEvent.META_ALT_LEFT_ON) != 0);
340         assertTrue((mask & KeyEvent.META_ALT_RIGHT_ON) != 0);
341         assertTrue((mask & KeyEvent.META_CTRL_ON) != 0);
342         assertTrue((mask & KeyEvent.META_CTRL_LEFT_ON) != 0);
343         assertTrue((mask & KeyEvent.META_CTRL_RIGHT_ON) != 0);
344         assertTrue((mask & KeyEvent.META_META_ON) != 0);
345         assertTrue((mask & KeyEvent.META_META_LEFT_ON) != 0);
346         assertTrue((mask & KeyEvent.META_META_RIGHT_ON) != 0);
347         assertTrue((mask & KeyEvent.META_SYM_ON) != 0);
348         assertTrue((mask & KeyEvent.META_FUNCTION_ON) != 0);
349 
350         assertFalse((mask & KeyEvent.META_CAPS_LOCK_ON) != 0);
351         assertFalse((mask & KeyEvent.META_NUM_LOCK_ON) != 0);
352         assertFalse((mask & KeyEvent.META_SCROLL_LOCK_ON) != 0);
353     }
354 
355     @Test
testIsModifierKey()356     public void testIsModifierKey() {
357         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_SHIFT_LEFT));
358         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_SHIFT_RIGHT));
359         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_ALT_LEFT));
360         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_ALT_RIGHT));
361         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_CTRL_LEFT));
362         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_CTRL_RIGHT));
363         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_META_LEFT));
364         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_META_RIGHT));
365         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_SYM));
366         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_NUM));
367         assertTrue(KeyEvent.isModifierKey(KeyEvent.KEYCODE_FUNCTION));
368 
369         assertFalse(KeyEvent.isModifierKey(KeyEvent.KEYCODE_0));
370     }
371 
372     private static final int UNDEFINED_META_STATE = 0x80000000;
373 
374     @Test
testNormalizeMetaState()375     public void testNormalizeMetaState() {
376         // Already normalized values.
377         assertEquals(0, KeyEvent.normalizeMetaState(0));
378         assertEquals(KeyEvent.getModifierMetaStateMask(),
379                 KeyEvent.normalizeMetaState(KeyEvent.getModifierMetaStateMask()));
380 
381         // Values that require normalization.
382         assertEquals(KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON,
383                 KeyEvent.normalizeMetaState(KeyEvent.META_SHIFT_LEFT_ON));
384         assertEquals(KeyEvent.META_SHIFT_RIGHT_ON | KeyEvent.META_SHIFT_ON,
385                 KeyEvent.normalizeMetaState(KeyEvent.META_SHIFT_RIGHT_ON));
386         assertEquals(KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON,
387                 KeyEvent.normalizeMetaState(KeyEvent.META_ALT_LEFT_ON));
388         assertEquals(KeyEvent.META_ALT_RIGHT_ON | KeyEvent.META_ALT_ON,
389                 KeyEvent.normalizeMetaState(KeyEvent.META_ALT_RIGHT_ON));
390         assertEquals(KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON,
391                 KeyEvent.normalizeMetaState(KeyEvent.META_CTRL_LEFT_ON));
392         assertEquals(KeyEvent.META_CTRL_RIGHT_ON | KeyEvent.META_CTRL_ON,
393                 KeyEvent.normalizeMetaState(KeyEvent.META_CTRL_RIGHT_ON));
394         assertEquals(KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON,
395                 KeyEvent.normalizeMetaState(KeyEvent.META_META_LEFT_ON));
396         assertEquals(KeyEvent.META_META_RIGHT_ON | KeyEvent.META_META_ON,
397                 KeyEvent.normalizeMetaState(KeyEvent.META_META_RIGHT_ON));
398         assertEquals(KeyEvent.META_CAPS_LOCK_ON,
399                 KeyEvent.normalizeMetaState(MetaKeyKeyListener.META_CAP_LOCKED));
400         assertEquals(KeyEvent.META_ALT_ON,
401                 KeyEvent.normalizeMetaState(MetaKeyKeyListener.META_ALT_LOCKED));
402         assertEquals(KeyEvent.META_SYM_ON,
403                 KeyEvent.normalizeMetaState(MetaKeyKeyListener.META_SYM_LOCKED));
404         assertEquals(KeyEvent.META_SHIFT_ON,
405                 KeyEvent.normalizeMetaState(KeyEvent.META_SHIFT_ON | UNDEFINED_META_STATE));
406     }
407 
408     @Test
testMetaStateHasNoModifiers()409     public void testMetaStateHasNoModifiers() {
410         assertTrue(KeyEvent.metaStateHasNoModifiers(0));
411         assertTrue(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_CAPS_LOCK_ON));
412         assertTrue(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_NUM_LOCK_ON));
413         assertTrue(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_SCROLL_LOCK_ON));
414 
415         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_SHIFT_ON));
416         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_SHIFT_LEFT_ON));
417         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_SHIFT_RIGHT_ON));
418         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_ALT_ON));
419         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_ALT_LEFT_ON));
420         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_ALT_RIGHT_ON));
421         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_CTRL_ON));
422         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_CTRL_LEFT_ON));
423         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_CTRL_RIGHT_ON));
424         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_META_ON));
425         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_META_LEFT_ON));
426         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_META_RIGHT_ON));
427         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_SYM_ON));
428         assertFalse(KeyEvent.metaStateHasNoModifiers(KeyEvent.META_FUNCTION_ON));
429     }
430 
431     @Test
testMetaStateHasModifiers()432     public void testMetaStateHasModifiers() {
433         assertTrue(KeyEvent.metaStateHasModifiers(0, 0));
434         assertTrue(KeyEvent.metaStateHasModifiers(
435                 KeyEvent.META_NUM_LOCK_ON | KeyEvent.META_CAPS_LOCK_ON
436                         | KeyEvent.META_SCROLL_LOCK_ON, 0));
437         assertTrue(KeyEvent.metaStateHasModifiers(
438                 KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON,
439                 KeyEvent.META_SHIFT_LEFT_ON));
440         assertTrue(KeyEvent.metaStateHasModifiers(
441                 KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON,
442                 KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON));
443         assertTrue(KeyEvent.metaStateHasModifiers(
444                 KeyEvent.META_SHIFT_LEFT_ON,
445                 KeyEvent.META_SHIFT_LEFT_ON));
446         assertTrue(KeyEvent.metaStateHasModifiers(
447                 KeyEvent.META_NUM_LOCK_ON | KeyEvent.META_CAPS_LOCK_ON
448                         | KeyEvent.META_SCROLL_LOCK_ON | KeyEvent.META_SHIFT_LEFT_ON,
449                 KeyEvent.META_SHIFT_LEFT_ON));
450         assertTrue(KeyEvent.metaStateHasModifiers(
451                 KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON,
452                 KeyEvent.META_SHIFT_ON));
453         assertTrue(KeyEvent.metaStateHasModifiers(
454                 KeyEvent.META_ALT_ON | KeyEvent.META_ALT_RIGHT_ON,
455                 KeyEvent.META_ALT_ON));
456         assertTrue(KeyEvent.metaStateHasModifiers(
457                 KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON,
458                 KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON));
459         assertTrue(KeyEvent.metaStateHasModifiers(
460                 KeyEvent.META_CTRL_RIGHT_ON | KeyEvent.META_META_LEFT_ON,
461                 KeyEvent.META_CTRL_RIGHT_ON | KeyEvent.META_META_ON));
462         assertTrue(KeyEvent.metaStateHasModifiers(
463                 KeyEvent.META_SYM_ON | KeyEvent.META_FUNCTION_ON | KeyEvent.META_CAPS_LOCK_ON,
464                 KeyEvent.META_SYM_ON | KeyEvent.META_FUNCTION_ON));
465 
466         assertFalse(KeyEvent.metaStateHasModifiers(0, KeyEvent.META_SHIFT_ON));
467         assertFalse(KeyEvent.metaStateHasModifiers(
468                 KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_LEFT_ON,
469                 KeyEvent.META_SHIFT_ON));
470         assertFalse(KeyEvent.metaStateHasModifiers(
471                 KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON,
472                 KeyEvent.META_SHIFT_ON));
473         assertFalse(KeyEvent.metaStateHasModifiers(
474                 KeyEvent.META_ALT_LEFT_ON,
475                 KeyEvent.META_ALT_RIGHT_ON));
476         assertFalse(KeyEvent.metaStateHasModifiers(
477                 KeyEvent.META_ALT_LEFT_ON,
478                 KeyEvent.META_CTRL_LEFT_ON));
479 
480         final int[] invalidModifiers = new int[] {
481                 KeyEvent.META_CAPS_LOCK_ON,
482                 KeyEvent.META_NUM_LOCK_ON,
483                 KeyEvent.META_SCROLL_LOCK_ON,
484                 MetaKeyKeyListener.META_CAP_LOCKED,
485                 MetaKeyKeyListener.META_ALT_LOCKED,
486                 MetaKeyKeyListener.META_SYM_LOCKED,
487                 KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON,
488                 KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_RIGHT_ON,
489                 KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON| KeyEvent.META_SHIFT_RIGHT_ON,
490                 KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON,
491                 KeyEvent.META_ALT_ON | KeyEvent.META_ALT_RIGHT_ON,
492                 KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON| KeyEvent.META_ALT_RIGHT_ON,
493                 KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON,
494                 KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_RIGHT_ON,
495                 KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON| KeyEvent.META_CTRL_RIGHT_ON,
496                 KeyEvent.META_META_ON | KeyEvent.META_META_LEFT_ON,
497                 KeyEvent.META_META_ON | KeyEvent.META_META_RIGHT_ON,
498                 KeyEvent.META_META_ON | KeyEvent.META_META_LEFT_ON| KeyEvent.META_META_RIGHT_ON,
499         };
500         for (int modifiers : invalidModifiers) {
501             try {
502                 KeyEvent.metaStateHasModifiers(0, modifiers);
503                 Assert.fail("Expected IllegalArgumentException");
504             } catch (IllegalArgumentException ex) {
505             }
506         }
507 
508         assertFalse(KeyEvent.metaStateHasModifiers(0, UNDEFINED_META_STATE));
509     }
510 
511     @Test
testHasNoModifiers()512     public void testHasNoModifiers() {
513         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
514                 KeyEvent.KEYCODE_A, 0, KeyEvent.META_CAPS_LOCK_ON);
515         assertTrue(mKeyEvent.hasNoModifiers());
516 
517         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
518                 KeyEvent.KEYCODE_A, 0, KeyEvent.META_CAPS_LOCK_ON | KeyEvent.META_SHIFT_ON);
519         assertFalse(mKeyEvent.hasNoModifiers());
520     }
521 
522     @Test
testHasModifiers()523     public void testHasModifiers() {
524         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
525                 KeyEvent.KEYCODE_A, 0, KeyEvent.META_CAPS_LOCK_ON);
526         assertTrue(mKeyEvent.hasModifiers(0));
527 
528         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
529                 KeyEvent.KEYCODE_A, 0, KeyEvent.META_CAPS_LOCK_ON | KeyEvent.META_SHIFT_ON);
530         assertTrue(mKeyEvent.hasModifiers(KeyEvent.META_SHIFT_ON));
531 
532         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
533                 KeyEvent.KEYCODE_A, 0,
534                 KeyEvent.META_CAPS_LOCK_ON | KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_RIGHT_ON);
535         assertFalse(mKeyEvent.hasModifiers(KeyEvent.META_SHIFT_LEFT_ON));
536     }
537 
538     @Test
testGetDisplayLabel()539     public void testGetDisplayLabel() {
540         assertTrue(mKeyEvent.getDisplayLabel() > 0);
541     }
542 
543     @Test
testIsSystem()544     public void testIsSystem() {
545         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU);
546         assertTrue(mKeyEvent.isSystem());
547 
548         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SOFT_RIGHT);
549         assertTrue(mKeyEvent.isSystem());
550 
551         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HOME);
552         assertTrue(mKeyEvent.isSystem());
553 
554         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
555         assertTrue(mKeyEvent.isSystem());
556 
557         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CALL);
558         assertTrue(mKeyEvent.isSystem());
559 
560         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENDCALL);
561         assertTrue(mKeyEvent.isSystem());
562 
563         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_UP);
564         assertTrue(mKeyEvent.isSystem());
565 
566         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_VOLUME_DOWN);
567         assertTrue(mKeyEvent.isSystem());
568 
569         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER);
570         assertTrue(mKeyEvent.isSystem());
571 
572         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SEARCH);
573         assertTrue(mKeyEvent.isSystem());
574 
575         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK);
576         assertTrue(mKeyEvent.isSystem());
577 
578         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_CAMERA);
579         assertTrue(mKeyEvent.isSystem());
580 
581         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS);
582         assertTrue(mKeyEvent.isSystem());
583 
584         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_STEM_PRIMARY);
585         assertTrue(mKeyEvent.isSystem());
586 
587         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
588         assertFalse(mKeyEvent.isSystem());
589     }
590 
591     @Test
testIsPrintingKey()592     public void testIsPrintingKey() {
593         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, Character.SPACE_SEPARATOR);
594         assertTrue(mKeyEvent.isPrintingKey());
595 
596         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, Character.LINE_SEPARATOR);
597         assertTrue(mKeyEvent.isPrintingKey());
598 
599         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, Character.PARAGRAPH_SEPARATOR);
600         assertTrue(mKeyEvent.isPrintingKey());
601 
602         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, Character.CONTROL);
603         assertTrue(mKeyEvent.isPrintingKey());
604 
605         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, Character.FORMAT);
606         assertTrue(mKeyEvent.isPrintingKey());
607 
608         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
609         assertTrue(mKeyEvent.isPrintingKey());
610     }
611 
612     @Test
testIsMediaSessionKey()613     public void testIsMediaSessionKey() {
614         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_PLAY));
615         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_PAUSE));
616         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
617         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_HEADSETHOOK));
618         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_STOP));
619         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_NEXT));
620         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_PREVIOUS));
621         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_REWIND));
622         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_RECORD));
623         assertTrue(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD));
624 
625         assertFalse(KeyEvent.isMediaSessionKey(KeyEvent.KEYCODE_0));
626     }
627 
628     @Test
testGetMatch()629     public void testGetMatch() {
630         // Our default key event is down + 0, so we expect getMatch to return our '0' character
631         assertEquals('0', mKeyEvent.getMatch(new char[] { '0', '1', '2' }));
632 
633         // Our default key event is down + 0, so we expect getMatch to return the default 0
634         assertEquals('\0', mKeyEvent.getMatch(new char[] { 'A', 'B', 'C' }));
635 
636         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_S);
637         assertEquals('S', mKeyEvent.getMatch(new char[] { '2', 'S' }));
638     }
639 
640     @Test
testGetMatchWithMeta()641     public void testGetMatchWithMeta() {
642         mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
643         // With no meta state, we're expecting our key event to match the lowercase 'a' since
644         // it's the first good match in the passed array
645         assertEquals('a', mKeyEvent.getMatch(new char[] { 'a', 'A' }, 0));
646         // With SHIFT_ON meta state, we're expecting the same key event to match the uppercase
647         // 'a' since it's a better match now
648         assertEquals('A', mKeyEvent.getMatch(new char[] { 'a', 'A' }, KeyEvent.META_SHIFT_ON));
649     }
650 
651     @Test
testGetAction()652     public void testGetAction() {
653         assertEquals(KeyEvent.ACTION_DOWN, mKeyEvent.getAction());
654     }
655 
656     @Test
testGetRepeatCount()657     public void testGetRepeatCount() {
658         int repeatCount = 1;
659         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_MULTIPLE,
660                 KeyEvent.KEYCODE_0, repeatCount);
661         assertEquals(repeatCount, mKeyEvent.getRepeatCount());
662     }
663 
664     @Test
testWriteToParcel()665     public void testWriteToParcel() {
666         KeyEvent keyEvent = parcelUnparcel(mKeyEvent);
667 
668         assertEquals(mKeyEvent.getAction(), keyEvent.getAction());
669         assertEquals(mKeyEvent.getKeyCode(), keyEvent.getKeyCode());
670         assertEquals(mKeyEvent.getRepeatCount(), keyEvent.getRepeatCount());
671         assertEquals(mKeyEvent.getMetaState(), keyEvent.getMetaState());
672         assertEquals(mKeyEvent.getDeviceId(), keyEvent.getDeviceId());
673         assertEquals(mKeyEvent.getScanCode(), keyEvent.getScanCode());
674         assertEquals(mKeyEvent.getFlags(), keyEvent.getFlags());
675         assertEquals(mKeyEvent.getDownTime(), keyEvent.getDownTime());
676         assertEquals(mKeyEvent.getEventTime(), keyEvent.getEventTime());
677         assertEquals(mKeyEvent.getCharacters(), keyEvent.getCharacters());
678     }
679 
680     @Test
testDescribeContents()681     public void testDescribeContents() {
682         // make sure it never shrow any exception.
683         mKeyEvent.describeContents();
684     }
685 
686     @Test
testGetKeyCode()687     public void testGetKeyCode() {
688         assertEquals(KeyEvent.KEYCODE_0, mKeyEvent.getKeyCode());
689     }
690 
691     @Test
testGetFlags()692     public void testGetFlags() {
693         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
694                 KeyEvent.KEYCODE_0, 5, KeyEvent.META_SHIFT_ON, 1, 1, KeyEvent.FLAG_WOKE_HERE);
695         assertEquals(KeyEvent.FLAG_WOKE_HERE, mKeyEvent.getFlags());
696 
697         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
698                 KeyEvent.KEYCODE_0, 5, KeyEvent.META_SHIFT_ON, 1, 1, KeyEvent.FLAG_SOFT_KEYBOARD);
699         assertEquals(KeyEvent.FLAG_SOFT_KEYBOARD, mKeyEvent.getFlags());
700     }
701 
702     @Test
testGetScanCode()703     public void testGetScanCode() {
704         int scanCode = 1;
705         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
706                 KeyEvent.KEYCODE_0, 5, KeyEvent.META_SHIFT_ON, 1, scanCode);
707         assertEquals(scanCode, mKeyEvent.getScanCode());
708     }
709 
710     @Test
testChangeAction()711     public void testChangeAction() {
712         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
713                 KeyEvent.KEYCODE_0, 5, KeyEvent.META_SHIFT_ON, 1, 1, KeyEvent.FLAG_WOKE_HERE);
714 
715         KeyEvent newEvent = KeyEvent.changeAction(mKeyEvent, KeyEvent.ACTION_UP);
716         assertEquals(KeyEvent.ACTION_UP, newEvent.getAction());
717         assertEquals(mKeyEvent.getFlags(), newEvent.getFlags());
718         assertEquals(mKeyEvent.getCharacters(), newEvent.getCharacters());
719         assertEquals(mKeyEvent.getDisplayLabel(), newEvent.getDisplayLabel());
720         assertEquals(mKeyEvent.getDeviceId(), newEvent.getDeviceId());
721         assertEquals(mKeyEvent.getDownTime(), newEvent.getDownTime());
722         assertEquals(mKeyEvent.getEventTime(), newEvent.getEventTime());
723         assertEquals(mKeyEvent.getKeyCode(), newEvent.getKeyCode());
724         assertEquals(mKeyEvent.getRepeatCount(), newEvent.getRepeatCount());
725     }
726 
727     @Test
testChangeFlags()728     public void testChangeFlags() {
729         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
730                 KeyEvent.KEYCODE_0, 5, KeyEvent.META_SHIFT_ON, 1, 1, KeyEvent.FLAG_WOKE_HERE);
731 
732         KeyEvent newEvent = KeyEvent.changeFlags(mKeyEvent, KeyEvent.FLAG_FROM_SYSTEM);
733         assertEquals(KeyEvent.FLAG_FROM_SYSTEM, newEvent.getFlags());
734         assertEquals(mKeyEvent.getAction(), newEvent.getAction());
735         assertEquals(mKeyEvent.getCharacters(), newEvent.getCharacters());
736         assertEquals(mKeyEvent.getDisplayLabel(), newEvent.getDisplayLabel());
737         assertEquals(mKeyEvent.getDeviceId(), newEvent.getDeviceId());
738         assertEquals(mKeyEvent.getDownTime(), newEvent.getDownTime());
739         assertEquals(mKeyEvent.getEventTime(), newEvent.getEventTime());
740         assertEquals(mKeyEvent.getKeyCode(), newEvent.getKeyCode());
741         assertEquals(mKeyEvent.getRepeatCount(), newEvent.getRepeatCount());
742     }
743 
744     @Test
testChangeTimeRepeat()745     public void testChangeTimeRepeat() {
746         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
747                 KeyEvent.KEYCODE_0, 5, KeyEvent.META_SHIFT_ON, 1, 1, KeyEvent.FLAG_WOKE_HERE);
748 
749         long newEventTime = SystemClock.uptimeMillis();
750         int newRepeat = mKeyEvent.getRepeatCount() + 1;
751         KeyEvent newEvent = KeyEvent.changeTimeRepeat(mKeyEvent, newEventTime, newRepeat);
752         assertEquals(newEventTime, newEvent.getEventTime());
753         assertEquals(newRepeat, newEvent.getRepeatCount());
754         assertEquals(mKeyEvent.getFlags(), newEvent.getFlags());
755         assertEquals(mKeyEvent.getAction(), newEvent.getAction());
756         assertEquals(mKeyEvent.getCharacters(), newEvent.getCharacters());
757         assertEquals(mKeyEvent.getDisplayLabel(), newEvent.getDisplayLabel());
758         assertEquals(mKeyEvent.getDeviceId(), newEvent.getDeviceId());
759         assertEquals(mKeyEvent.getDownTime(), newEvent.getDownTime());
760         assertEquals(mKeyEvent.getKeyCode(), newEvent.getKeyCode());
761     }
762 
763     @Test
testAccessSource()764     public void testAccessSource() {
765         mKeyEvent.setSource(InputDevice.SOURCE_KEYBOARD);
766         assertEquals(InputDevice.SOURCE_KEYBOARD, mKeyEvent.getSource());
767 
768         mKeyEvent.setSource(InputDevice.SOURCE_HDMI);
769         assertEquals(InputDevice.SOURCE_HDMI, mKeyEvent.getSource());
770     }
771 
772     @Test
testMetaOn()773     public void testMetaOn() {
774         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
775                 KeyEvent.KEYCODE_A, 0, KeyEvent.META_CAPS_LOCK_ON | KeyEvent.META_SHIFT_ON);
776         assertTrue(mKeyEvent.isCapsLockOn());
777         assertFalse(mKeyEvent.isNumLockOn());
778         assertFalse(mKeyEvent.isScrollLockOn());
779 
780         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
781                 KeyEvent.KEYCODE_B, 1, KeyEvent.META_NUM_LOCK_ON | KeyEvent.META_SHIFT_ON);
782         assertFalse(mKeyEvent.isCapsLockOn());
783         assertTrue(mKeyEvent.isNumLockOn());
784         assertFalse(mKeyEvent.isScrollLockOn());
785 
786         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN,
787                 KeyEvent.KEYCODE_C, 2, KeyEvent.META_SCROLL_LOCK_ON | KeyEvent.META_SHIFT_ON);
788         assertFalse(mKeyEvent.isCapsLockOn());
789         assertFalse(mKeyEvent.isNumLockOn());
790         assertTrue(mKeyEvent.isScrollLockOn());
791     }
792 
793     @Test
testIsLongPress()794     public void testIsLongPress() {
795         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A,
796                 1, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS,
797                 InputDevice.SOURCE_TOUCHSCREEN);
798         assertTrue(mKeyEvent.isLongPress());
799 
800         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A,
801                 1, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_TOUCHSCREEN);
802         assertFalse(mKeyEvent.isLongPress());
803     }
804 
805     @Test
testKeyCodeFromString()806     public void testKeyCodeFromString() {
807         assertEquals(KeyEvent.KEYCODE_A, KeyEvent.keyCodeFromString("KEYCODE_A"));
808         assertEquals(KeyEvent.KEYCODE_A, KeyEvent.keyCodeFromString("A"));
809         assertEquals(KeyEvent.KEYCODE_A,
810                 KeyEvent.keyCodeFromString(Integer.toString(KeyEvent.KEYCODE_A)));
811         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("keycode_a"));
812         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("a"));
813         assertEquals(0, KeyEvent.keyCodeFromString("0"));
814         assertEquals(1, KeyEvent.keyCodeFromString("1"));
815         assertEquals(KeyEvent.KEYCODE_HOME, KeyEvent.keyCodeFromString("3"));
816         assertEquals(KeyEvent.KEYCODE_POWER,
817                 KeyEvent.keyCodeFromString(Integer.toString(KeyEvent.KEYCODE_POWER)));
818         assertEquals(KeyEvent.KEYCODE_MENU,
819                 KeyEvent.keyCodeFromString(Integer.toString(KeyEvent.KEYCODE_MENU)));
820         assertEquals(KeyEvent.KEYCODE_BACK, KeyEvent.keyCodeFromString("BACK"));
821         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("back"));
822 
823         assertEquals(KeyEvent.KEYCODE_UNKNOWN,
824                 KeyEvent.keyCodeFromString("KEYCODE_NOT_A_REAL_KEYCODE"));
825         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("NOT_A_REAL_KEYCODE"));
826         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("-1"));
827         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("1001"));
828         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("KEYCODE_123"));
829         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("KEYCODE"));
830         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString("KEYCODE_"));
831         assertEquals(KeyEvent.KEYCODE_UNKNOWN, KeyEvent.keyCodeFromString(""));
832         assertEquals(KeyEvent.getMaxKeyCode(),
833                 KeyEvent.keyCodeFromString(Integer.toString(KeyEvent.getMaxKeyCode())));
834         assertEquals(KeyEvent.KEYCODE_UNKNOWN,
835                 KeyEvent.keyCodeFromString(Integer.toString(KeyEvent.getMaxKeyCode() + 1)));
836     }
837 
838     @Test
testNativeConverter()839     public void testNativeConverter() {
840         mKeyEvent = new KeyEvent(mDownTime, mEventTime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A,
841                 1, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_TOUCHSCREEN);
842         nativeKeyEventTest(mKeyEvent);
843     }
844 
845     @Test
testNativeToJavaConverter()846     public void testNativeToJavaConverter() {
847         KeyEvent javaKeyEvent = new KeyEvent(mDownTime, mEventTime,
848                 KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 1, 0,
849                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0,
850                         InputDevice.SOURCE_KEYBOARD);
851         KeyEvent keyEventFromNative = obtainKeyEventCopyFromNative(javaKeyEvent);
852         assertNotNull(keyEventFromNative);
853         assertNotSame(javaKeyEvent, keyEventFromNative);
854         assertEquals(javaKeyEvent.getDownTime(), keyEventFromNative.getDownTime());
855         assertEquals(javaKeyEvent.getEventTime(), keyEventFromNative.getEventTime());
856         assertEquals(javaKeyEvent.getAction(), keyEventFromNative.getAction());
857         assertEquals(javaKeyEvent.getKeyCode(), keyEventFromNative.getKeyCode());
858         assertEquals(javaKeyEvent.getRepeatCount(), keyEventFromNative.getRepeatCount());
859         assertEquals(javaKeyEvent.getMetaState(), keyEventFromNative.getMetaState());
860         assertEquals(javaKeyEvent.getDeviceId(), keyEventFromNative.getDeviceId());
861         assertEquals(javaKeyEvent.getScanCode(), keyEventFromNative.getScanCode());
862         assertEquals(javaKeyEvent.getFlags(), keyEventFromNative.getFlags());
863         assertEquals(javaKeyEvent.getSource(), keyEventFromNative.getSource());
864     }
865 
866     @Test
testNativeToJavaConverterMemoryLeak()867     public void testNativeToJavaConverterMemoryLeak() {
868         final KeyEvent javaKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
869 
870         try (NativeHeapLeakDetector d = new NativeHeapLeakDetector()) {
871             for (int iteration = 0; iteration < NUM_KEY_EVENT_ALLOCATIONS; ++iteration) {
872                 obtainKeyEventCopyFromNative(javaKeyEvent);
873             }
874         }
875     }
876 
877     @Test
testJavaToNativeConverterMemoryLeak()878     public void testJavaToNativeConverterMemoryLeak() {
879         final KeyEvent javaKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
880 
881         try (NativeHeapLeakDetector d = new NativeHeapLeakDetector()) {
882             for (int iteration = 0; iteration < NUM_KEY_EVENT_ALLOCATIONS; ++iteration) {
883                 obtainNativeKeyEventCopyFromJava(javaKeyEvent);
884             }
885         }
886     }
887 
888     // Parcel a KeyEvent, then create a new KeyEvent from this parcel. Return the new KeyEvent
parcelUnparcel(KeyEvent keyEvent)889     private KeyEvent parcelUnparcel(KeyEvent keyEvent) {
890         Parcel parcel = Parcel.obtain();
891         keyEvent.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
892         parcel.setDataPosition(0);
893 
894         KeyEvent keyEventFromParcel = KeyEvent.CREATOR.createFromParcel(parcel);
895         parcel.recycle();
896         return keyEventFromParcel;
897     }
898 }
899