blob: 1dd32c447b726e1971d21435b8b5395d72fc66ec [file] [log] [blame]
Arpit Singhb3b3f732023-07-04 14:30:05 +00001/*
2 * Copyright 2023 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#include "KeyboardInputMapper.h"
18
Harry Cuttsf673e672024-11-08 17:51:40 +000019#include <cstdint>
20#include <list>
21#include <memory>
22#include <optional>
23#include <string>
Arpit Singhb3b3f732023-07-04 14:30:05 +000024
Harry Cuttsf673e672024-11-08 17:51:40 +000025#include <android/input.h>
26#include <android/keycodes.h>
27#include <com_android_input_flags.h>
28#include <flag_macros.h>
29#include <ftl/flags.h>
30#include <gtest/gtest.h>
31#include <input/DisplayViewport.h>
32#include <input/Input.h>
33#include <input/InputDevice.h>
34#include <ui/LogicalDisplayId.h>
35#include <ui/Rotation.h>
Harry Cuttsd62330d2024-11-11 13:43:13 +000036#include <utils/Errors.h>
Harry Cuttsf673e672024-11-08 17:51:40 +000037
38#include "EventHub.h"
Arpit Singhb3b3f732023-07-04 14:30:05 +000039#include "InputMapperTest.h"
40#include "InterfaceMocks.h"
Harry Cuttsf673e672024-11-08 17:51:40 +000041#include "NotifyArgs.h"
42#include "TestConstants.h"
David Padlipsky48fd8842024-10-18 03:36:58 +000043#include "TestEventMatchers.h"
Arpit Singhb3b3f732023-07-04 14:30:05 +000044
45#define TAG "KeyboardInputMapper_test"
46
47namespace android {
48
Harry Cuttsd62330d2024-11-11 13:43:13 +000049using namespace ftl::flag_operators;
Arpit Singhb3b3f732023-07-04 14:30:05 +000050using testing::_;
David Padlipsky48fd8842024-10-18 03:36:58 +000051using testing::AllOf;
Harry Cuttsd62330d2024-11-11 13:43:13 +000052using testing::AnyOf;
Arpit Singh82e413e2023-10-10 19:30:58 +000053using testing::Args;
Arpit Singhb3b3f732023-07-04 14:30:05 +000054using testing::DoAll;
Harry Cuttsd62330d2024-11-11 13:43:13 +000055using testing::IsEmpty;
Arpit Singhb3b3f732023-07-04 14:30:05 +000056using testing::Return;
Harry Cuttsd62330d2024-11-11 13:43:13 +000057using testing::ReturnArg;
58using testing::SaveArg;
Arpit Singhb3b3f732023-07-04 14:30:05 +000059using testing::SetArgPointee;
David Padlipsky48fd8842024-10-18 03:36:58 +000060using testing::VariantWith;
Arpit Singhb3b3f732023-07-04 14:30:05 +000061
Harry Cuttsf673e672024-11-08 17:51:40 +000062namespace {
63
64// Arbitrary display properties.
65constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
66constexpr int32_t DISPLAY_WIDTH = 480;
67constexpr int32_t DISPLAY_HEIGHT = 800;
Harry Cuttsd62330d2024-11-11 13:43:13 +000068
69DisplayViewport createPrimaryViewport(ui::Rotation orientation) {
70 const bool isRotated =
71 orientation == ui::Rotation::Rotation90 || orientation == ui::Rotation::Rotation270;
72 DisplayViewport v;
73 v.displayId = DISPLAY_ID;
74 v.orientation = orientation;
75 v.logicalRight = isRotated ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
76 v.logicalBottom = isRotated ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
77 v.physicalRight = isRotated ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
78 v.physicalBottom = isRotated ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
79 v.deviceWidth = isRotated ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
80 v.deviceHeight = isRotated ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
81 v.isActive = true;
82 v.uniqueId = "local:1";
83 return v;
84}
Harry Cuttsf673e672024-11-08 17:51:40 +000085
86} // namespace
87
Arpit Singhb3b3f732023-07-04 14:30:05 +000088/**
89 * Unit tests for KeyboardInputMapper.
90 */
91class KeyboardInputMapperUnitTest : public InputMapperUnitTest {
92protected:
Harry Cuttsd62330d2024-11-11 13:43:13 +000093 const KeyboardLayoutInfo DEVICE_KEYBOARD_LAYOUT_INFO = KeyboardLayoutInfo("en-US", "qwerty");
94
Arpit Singhb3b3f732023-07-04 14:30:05 +000095 sp<FakeInputReaderPolicy> mFakePolicy;
96 const std::unordered_map<int32_t, int32_t> mKeyCodeMap{{KEY_0, AKEYCODE_0},
97 {KEY_A, AKEYCODE_A},
98 {KEY_LEFTCTRL, AKEYCODE_CTRL_LEFT},
99 {KEY_LEFTALT, AKEYCODE_ALT_LEFT},
100 {KEY_RIGHTALT, AKEYCODE_ALT_RIGHT},
101 {KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT},
102 {KEY_RIGHTSHIFT, AKEYCODE_SHIFT_RIGHT},
103 {KEY_FN, AKEYCODE_FUNCTION},
104 {KEY_LEFTCTRL, AKEYCODE_CTRL_LEFT},
105 {KEY_RIGHTCTRL, AKEYCODE_CTRL_RIGHT},
106 {KEY_LEFTMETA, AKEYCODE_META_LEFT},
107 {KEY_RIGHTMETA, AKEYCODE_META_RIGHT},
108 {KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK},
109 {KEY_NUMLOCK, AKEYCODE_NUM_LOCK},
110 {KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK}};
111
112 void SetUp() override {
113 InputMapperUnitTest::SetUp();
114
115 // set key-codes expected in tests
Harry Cuttsd62330d2024-11-11 13:43:13 +0000116 for (const auto& [evdevCode, outKeycode] : mKeyCodeMap) {
117 addKeyByEvdevCode(evdevCode, outKeycode);
Arpit Singhb3b3f732023-07-04 14:30:05 +0000118 }
119
120 mFakePolicy = sp<FakeInputReaderPolicy>::make();
121 EXPECT_CALL(mMockInputReaderContext, getPolicy).WillRepeatedly(Return(mFakePolicy.get()));
122
Prabir Pradhan38636652024-07-23 21:59:36 +0000123 ON_CALL((*mDevice), getSources).WillByDefault(Return(AINPUT_SOURCE_KEYBOARD));
124
Arpit Singhb3b3f732023-07-04 14:30:05 +0000125 mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000126 AINPUT_SOURCE_KEYBOARD);
Arpit Singhb3b3f732023-07-04 14:30:05 +0000127 }
Harry Cuttsd62330d2024-11-11 13:43:13 +0000128
129 void addKeyByEvdevCode(int32_t evdevCode, int32_t keyCode, int32_t flags = 0) {
130 EXPECT_CALL(mMockEventHub, mapKey(EVENTHUB_ID, evdevCode, _, _, _, _, _))
131 .WillRepeatedly([=](int32_t, int32_t, int32_t, int32_t metaState,
132 int32_t* outKeycode, int32_t* outMetaState,
133 uint32_t* outFlags) {
134 if (outKeycode != nullptr) {
135 *outKeycode = keyCode;
136 }
137 if (outMetaState != nullptr) {
138 *outMetaState = metaState;
139 }
140 if (outFlags != nullptr) {
141 *outFlags = flags;
142 }
143 return NO_ERROR;
144 });
145 }
146
147 void addKeyByUsageCode(int32_t usageCode, int32_t keyCode, int32_t flags = 0) {
148 EXPECT_CALL(mMockEventHub, mapKey(EVENTHUB_ID, _, usageCode, _, _, _, _))
149 .WillRepeatedly([=](int32_t, int32_t, int32_t, int32_t metaState,
150 int32_t* outKeycode, int32_t* outMetaState,
151 uint32_t* outFlags) {
152 if (outKeycode != nullptr) {
153 *outKeycode = keyCode;
154 }
155 if (outMetaState != nullptr) {
156 *outMetaState = metaState;
157 }
158 if (outFlags != nullptr) {
159 *outFlags = flags;
160 }
161 return NO_ERROR;
162 });
163 }
164
165 void setDisplayOrientation(ui::Rotation orientation) {
166 EXPECT_CALL((*mDevice), getAssociatedViewport)
167 .WillRepeatedly(Return(createPrimaryViewport(orientation)));
168 std::list<NotifyArgs> args =
169 mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
170 InputReaderConfiguration::Change::DISPLAY_INFO);
171 ASSERT_EQ(0u, args.size());
172 }
173
174 NotifyKeyArgs expectSingleKeyArg(const std::list<NotifyArgs>& args) {
175 EXPECT_EQ(1u, args.size());
176 return std::get<NotifyKeyArgs>(args.front());
177 }
178
179 void testDPadKeyRotation(int32_t originalEvdevCode, int32_t originalKeyCode,
180 int32_t rotatedKeyCode, ui::LogicalDisplayId displayId = DISPLAY_ID) {
181 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, originalEvdevCode, 1);
182 NotifyKeyArgs args = expectSingleKeyArg(argsList);
183 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
184 ASSERT_EQ(originalEvdevCode, args.scanCode);
185 ASSERT_EQ(rotatedKeyCode, args.keyCode);
186 ASSERT_EQ(displayId, args.displayId);
187
188 argsList = process(ARBITRARY_TIME, EV_KEY, originalEvdevCode, 0);
189 args = expectSingleKeyArg(argsList);
190 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
191 ASSERT_EQ(originalEvdevCode, args.scanCode);
192 ASSERT_EQ(rotatedKeyCode, args.keyCode);
193 ASSERT_EQ(displayId, args.displayId);
194 }
Arpit Singhb3b3f732023-07-04 14:30:05 +0000195};
196
Harry Cuttsd62330d2024-11-11 13:43:13 +0000197TEST_F(KeyboardInputMapperUnitTest, GetSources) {
198 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mMapper->getSources());
199}
200
Arpit Singh82e413e2023-10-10 19:30:58 +0000201TEST_F(KeyboardInputMapperUnitTest, KeyPressTimestampRecorded) {
202 nsecs_t when = ARBITRARY_TIME;
203 std::vector<int32_t> keyCodes{KEY_0, KEY_A, KEY_LEFTCTRL, KEY_RIGHTALT, KEY_LEFTSHIFT};
204 EXPECT_CALL(mMockInputReaderContext, setLastKeyDownTimestamp)
205 .With(Args<0>(when))
206 .Times(keyCodes.size());
207 for (int32_t keyCode : keyCodes) {
208 process(when, EV_KEY, keyCode, 1);
209 process(when, EV_SYN, SYN_REPORT, 0);
210 process(when, EV_KEY, keyCode, 0);
211 process(when, EV_SYN, SYN_REPORT, 0);
212 }
213}
214
David Padlipsky48fd8842024-10-18 03:36:58 +0000215TEST_F(KeyboardInputMapperUnitTest, RepeatEventsDiscarded) {
216 std::list<NotifyArgs> args;
217 args += process(ARBITRARY_TIME, EV_KEY, KEY_0, 1);
218 args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
219
220 args += process(ARBITRARY_TIME, EV_KEY, KEY_0, 2);
221 args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
222
223 args += process(ARBITRARY_TIME, EV_KEY, KEY_0, 0);
224 args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
225
226 EXPECT_THAT(args,
227 ElementsAre(VariantWith<NotifyKeyArgs>(AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN),
228 WithKeyCode(AKEYCODE_0),
229 WithScanCode(KEY_0))),
230 VariantWith<NotifyKeyArgs>(AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP),
231 WithKeyCode(AKEYCODE_0),
232 WithScanCode(KEY_0)))));
233}
234
Harry Cuttsd62330d2024-11-11 13:43:13 +0000235TEST_F(KeyboardInputMapperUnitTest, Process_SimpleKeyPress) {
236 const int32_t USAGE_A = 0x070004;
237 addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE);
238 addKeyByUsageCode(USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
239
240 // Initial metastate is AMETA_NONE.
241 ASSERT_EQ(AMETA_NONE, mMapper->getMetaState());
242
243 // Key down by evdev code.
244 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
245 NotifyKeyArgs args = expectSingleKeyArg(argsList);
246 ASSERT_EQ(DEVICE_ID, args.deviceId);
247 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
248 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
249 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
250 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
251 ASSERT_EQ(KEY_HOME, args.scanCode);
252 ASSERT_EQ(AMETA_NONE, args.metaState);
253 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
254 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
255 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
256
257 // Key up by evdev code.
258 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
259 args = expectSingleKeyArg(argsList);
260 ASSERT_EQ(DEVICE_ID, args.deviceId);
261 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
262 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
263 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
264 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
265 ASSERT_EQ(KEY_HOME, args.scanCode);
266 ASSERT_EQ(AMETA_NONE, args.metaState);
267 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
268 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
269 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
270
271 // Key down by usage code.
272 argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_A);
273 argsList += process(ARBITRARY_TIME, EV_KEY, 0, 1);
274 args = expectSingleKeyArg(argsList);
275 ASSERT_EQ(DEVICE_ID, args.deviceId);
276 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
277 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
278 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
279 ASSERT_EQ(AKEYCODE_A, args.keyCode);
280 ASSERT_EQ(0, args.scanCode);
281 ASSERT_EQ(AMETA_NONE, args.metaState);
282 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
283 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
284 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
285
286 // Key up by usage code.
287 argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_A);
288 argsList += process(ARBITRARY_TIME + 1, EV_KEY, 0, 0);
289 args = expectSingleKeyArg(argsList);
290 ASSERT_EQ(DEVICE_ID, args.deviceId);
291 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
292 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
293 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
294 ASSERT_EQ(AKEYCODE_A, args.keyCode);
295 ASSERT_EQ(0, args.scanCode);
296 ASSERT_EQ(AMETA_NONE, args.metaState);
297 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
298 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
299 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
300}
301
302TEST_F(KeyboardInputMapperUnitTest, Process_UnknownKey) {
303 const int32_t USAGE_UNKNOWN = 0x07ffff;
304 EXPECT_CALL(mMockEventHub, mapKey(EVENTHUB_ID, KEY_UNKNOWN, USAGE_UNKNOWN, _, _, _, _))
305 .WillRepeatedly(Return(NAME_NOT_FOUND));
306
307 // Key down with unknown scan code or usage code.
308 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
309 argsList += process(ARBITRARY_TIME, EV_KEY, KEY_UNKNOWN, 1);
310 NotifyKeyArgs args = expectSingleKeyArg(argsList);
311 ASSERT_EQ(DEVICE_ID, args.deviceId);
312 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
313 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
314 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
315 ASSERT_EQ(0, args.keyCode);
316 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
317 ASSERT_EQ(AMETA_NONE, args.metaState);
318 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
319 ASSERT_EQ(0U, args.policyFlags);
320 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
321
322 // Key up with unknown scan code or usage code.
323 argsList = process(ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
324 argsList += process(ARBITRARY_TIME + 1, EV_KEY, KEY_UNKNOWN, 0);
325 args = expectSingleKeyArg(argsList);
326 ASSERT_EQ(DEVICE_ID, args.deviceId);
327 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
328 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
329 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
330 ASSERT_EQ(0, args.keyCode);
331 ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
332 ASSERT_EQ(AMETA_NONE, args.metaState);
333 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
334 ASSERT_EQ(0U, args.policyFlags);
335 ASSERT_EQ(ARBITRARY_TIME, args.downTime);
336}
337
338/**
339 * Ensure that the readTime is set to the time when the EV_KEY is received.
340 */
341TEST_F(KeyboardInputMapperUnitTest, Process_SendsReadTime) {
342 addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME);
343
344 // Key down
345 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, /*readTime=*/12, EV_KEY, KEY_HOME, 1);
346 ASSERT_EQ(12, expectSingleKeyArg(argsList).readTime);
347
348 // Key up
349 argsList = process(ARBITRARY_TIME, /*readTime=*/15, EV_KEY, KEY_HOME, 1);
350 ASSERT_EQ(15, expectSingleKeyArg(argsList).readTime);
351}
352
353TEST_F(KeyboardInputMapperUnitTest, Process_ShouldUpdateMetaState) {
354 addKeyByEvdevCode(KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT);
355 addKeyByEvdevCode(KEY_A, AKEYCODE_A);
356
357 EXPECT_CALL(mMockInputReaderContext, updateGlobalMetaState()).Times(2);
358
359 // Initial metastate is AMETA_NONE.
360 ASSERT_EQ(AMETA_NONE, mMapper->getMetaState());
361
362 // Metakey down.
363 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
364 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, expectSingleKeyArg(argsList).metaState);
365 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mMapper->getMetaState());
366
367 // Key down.
368 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_A, 1);
369 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, expectSingleKeyArg(argsList).metaState);
370 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mMapper->getMetaState());
371
372 // Key up.
373 argsList = process(ARBITRARY_TIME + 2, EV_KEY, KEY_A, 0);
374 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, expectSingleKeyArg(argsList).metaState);
375 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mMapper->getMetaState());
376
377 // Metakey up.
378 argsList = process(ARBITRARY_TIME + 3, EV_KEY, KEY_LEFTSHIFT, 0);
379 ASSERT_EQ(AMETA_NONE, expectSingleKeyArg(argsList).metaState);
380 ASSERT_EQ(AMETA_NONE, mMapper->getMetaState());
381}
382
383TEST_F(KeyboardInputMapperUnitTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
384 addKeyByEvdevCode(KEY_UP, AKEYCODE_DPAD_UP);
385 addKeyByEvdevCode(KEY_RIGHT, AKEYCODE_DPAD_RIGHT);
386 addKeyByEvdevCode(KEY_DOWN, AKEYCODE_DPAD_DOWN);
387 addKeyByEvdevCode(KEY_LEFT, AKEYCODE_DPAD_LEFT);
388
389 setDisplayOrientation(ui::Rotation::Rotation90);
390 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
391 ASSERT_NO_FATAL_FAILURE(
392 testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
393 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
394 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
395}
396
397TEST_F(KeyboardInputMapperUnitTest, Process_WhenOrientationAware_ShouldRotateDPad) {
398 addKeyByEvdevCode(KEY_UP, AKEYCODE_DPAD_UP);
399 addKeyByEvdevCode(KEY_RIGHT, AKEYCODE_DPAD_RIGHT);
400 addKeyByEvdevCode(KEY_DOWN, AKEYCODE_DPAD_DOWN);
401 addKeyByEvdevCode(KEY_LEFT, AKEYCODE_DPAD_LEFT);
402
403 mPropertyMap.addProperty("keyboard.orientationAware", "1");
404 mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
405 AINPUT_SOURCE_KEYBOARD);
406 setDisplayOrientation(ui::ROTATION_0);
407
408 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
409 ASSERT_NO_FATAL_FAILURE(
410 testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
411 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
412 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
413
414 setDisplayOrientation(ui::ROTATION_90);
415 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT));
416 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP));
417 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT));
418 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN));
419
420 setDisplayOrientation(ui::ROTATION_180);
421 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN));
422 ASSERT_NO_FATAL_FAILURE(
423 testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT));
424 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP));
425 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT));
426
427 setDisplayOrientation(ui::ROTATION_270);
428 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT));
429 ASSERT_NO_FATAL_FAILURE(
430 testDPadKeyRotation(KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN));
431 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT));
432 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP));
433
434 // Special case: if orientation changes while key is down, we still emit the same keycode
435 // in the key up as we did in the key down.
436 setDisplayOrientation(ui::ROTATION_270);
437 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
438 NotifyKeyArgs args = expectSingleKeyArg(argsList);
439 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
440 ASSERT_EQ(KEY_UP, args.scanCode);
441 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
442
443 setDisplayOrientation(ui::ROTATION_180);
444 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
445 args = expectSingleKeyArg(argsList);
446 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
447 ASSERT_EQ(KEY_UP, args.scanCode);
448 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
449}
450
451TEST_F(KeyboardInputMapperUnitTest, DisplayIdConfigurationChange_NotOrientationAware) {
452 // If the keyboard is not orientation aware,
453 // key events should not be associated with a specific display id
454 addKeyByEvdevCode(KEY_UP, AKEYCODE_DPAD_UP);
455
456 // Display id should be LogicalDisplayId::INVALID without any display configuration.
457 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
458 ASSERT_GT(argsList.size(), 0u);
459 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
460 ASSERT_GT(argsList.size(), 0u);
461 ASSERT_EQ(ui::LogicalDisplayId::INVALID, std::get<NotifyKeyArgs>(argsList.front()).displayId);
462}
463
464TEST_F(KeyboardInputMapperUnitTest, DisplayIdConfigurationChange_OrientationAware) {
465 // If the keyboard is orientation aware,
466 // key events should be associated with the internal viewport
467 addKeyByEvdevCode(KEY_UP, AKEYCODE_DPAD_UP);
468
469 mPropertyMap.addProperty("keyboard.orientationAware", "1");
470 mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
471 AINPUT_SOURCE_KEYBOARD);
472
473 // Display id should be LogicalDisplayId::INVALID without any display configuration.
474 // ^--- already checked by the previous test
475
476 setDisplayOrientation(ui::ROTATION_0);
477 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
478 ASSERT_GT(argsList.size(), 0u);
479 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
480 ASSERT_GT(argsList.size(), 0u);
481 ASSERT_EQ(DISPLAY_ID, std::get<NotifyKeyArgs>(argsList.front()).displayId);
482
483 constexpr ui::LogicalDisplayId newDisplayId = ui::LogicalDisplayId{2};
484 DisplayViewport newViewport = createPrimaryViewport(ui::ROTATION_0);
485 newViewport.displayId = newDisplayId;
486 EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(newViewport));
487 argsList = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
488 InputReaderConfiguration::Change::DISPLAY_INFO);
489 ASSERT_EQ(0u, argsList.size());
490 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
491 ASSERT_GT(argsList.size(), 0u);
492 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
493 ASSERT_GT(argsList.size(), 0u);
494 ASSERT_EQ(newDisplayId, std::get<NotifyKeyArgs>(argsList.front()).displayId);
495}
496
497TEST_F(KeyboardInputMapperUnitTest, GetKeyCodeState) {
498 EXPECT_CALL(mMockEventHub, getKeyCodeState(EVENTHUB_ID, AKEYCODE_A))
499 .WillRepeatedly(Return(AKEY_STATE_DOWN));
500 ASSERT_EQ(AKEY_STATE_DOWN, mMapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
501
502 EXPECT_CALL(mMockEventHub, getKeyCodeState(EVENTHUB_ID, AKEYCODE_A))
503 .WillRepeatedly(Return(AKEY_STATE_UP));
504 ASSERT_EQ(AKEY_STATE_UP, mMapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
505}
506
507TEST_F(KeyboardInputMapperUnitTest, GetKeyCodeForKeyLocation) {
508 EXPECT_CALL(mMockEventHub, getKeyCodeForKeyLocation(EVENTHUB_ID, _))
509 .WillRepeatedly(ReturnArg<1>());
510 EXPECT_CALL(mMockEventHub, getKeyCodeForKeyLocation(EVENTHUB_ID, AKEYCODE_Y))
511 .WillRepeatedly(Return(AKEYCODE_Z));
512 ASSERT_EQ(AKEYCODE_Z, mMapper->getKeyCodeForKeyLocation(AKEYCODE_Y))
513 << "If a mapping is available, the result is equal to the mapping";
514
515 ASSERT_EQ(AKEYCODE_A, mMapper->getKeyCodeForKeyLocation(AKEYCODE_A))
516 << "If no mapping is available, the result is the key location";
517}
518
519TEST_F(KeyboardInputMapperUnitTest, GetScanCodeState) {
520 EXPECT_CALL(mMockEventHub, getScanCodeState(EVENTHUB_ID, KEY_A))
521 .WillRepeatedly(Return(AKEY_STATE_DOWN));
522 ASSERT_EQ(AKEY_STATE_DOWN, mMapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
523
524 EXPECT_CALL(mMockEventHub, getScanCodeState(EVENTHUB_ID, KEY_A))
525 .WillRepeatedly(Return(AKEY_STATE_UP));
526 ASSERT_EQ(AKEY_STATE_UP, mMapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
527}
528
529TEST_F(KeyboardInputMapperUnitTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
530 EXPECT_CALL(mMockEventHub,
531 hasLed(EVENTHUB_ID, AnyOf(LED_CAPSL, LED_NUML, LED_SCROLLL /*NOTYPO*/)))
532 .WillRepeatedly(Return(true));
533 bool capsLockLed = true; // Initially on
534 bool numLockLed = false; // Initially off
535 bool scrollLockLed = false; // Initially off
536 EXPECT_CALL(mMockEventHub, setLedState(EVENTHUB_ID, LED_CAPSL, _))
537 .WillRepeatedly(SaveArg<2>(&capsLockLed));
538 EXPECT_CALL(mMockEventHub, setLedState(EVENTHUB_ID, LED_NUML, _))
539 .WillRepeatedly(SaveArg<2>(&numLockLed));
540 EXPECT_CALL(mMockEventHub, setLedState(EVENTHUB_ID, LED_SCROLLL /*NOTYPO*/, _))
541 .WillRepeatedly(SaveArg<2>(&scrollLockLed));
542 addKeyByEvdevCode(KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK);
543 addKeyByEvdevCode(KEY_NUMLOCK, AKEYCODE_NUM_LOCK);
544 addKeyByEvdevCode(KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK);
545
546 // In real operation, mappers pass new LED states to InputReader (via the context), which then
547 // calls back to the mappers to apply that state. Mimic the same thing here with mocks.
548 int32_t ledMetaState;
549 EXPECT_CALL(mMockInputReaderContext, updateLedMetaState(_))
550 .WillRepeatedly([&](int32_t newState) {
551 ledMetaState = newState;
552 mMapper->updateLedState(false);
553 });
554 EXPECT_CALL(mMockInputReaderContext, getLedMetaState())
555 .WillRepeatedly(testing::ReturnPointee(&ledMetaState));
556
557 ASSERT_THAT(mMapper->reset(ARBITRARY_TIME), IsEmpty());
558
559 // Initial metastate is AMETA_NONE.
560 ASSERT_EQ(AMETA_NONE, mMapper->getMetaState());
561
562 // Initialization should have turned all of the lights off.
563 ASSERT_FALSE(capsLockLed);
564 ASSERT_FALSE(numLockLed);
565 ASSERT_FALSE(scrollLockLed);
566
567 // Toggle caps lock on.
568 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1);
569 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0);
570 ASSERT_TRUE(capsLockLed);
571 ASSERT_FALSE(numLockLed);
572 ASSERT_FALSE(scrollLockLed);
573 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mMapper->getMetaState());
574
575 // Toggle num lock on.
576 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1);
577 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0);
578 ASSERT_TRUE(capsLockLed);
579 ASSERT_TRUE(numLockLed);
580 ASSERT_FALSE(scrollLockLed);
581 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mMapper->getMetaState());
582
583 // Toggle caps lock off.
584 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1);
585 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0);
586 ASSERT_FALSE(capsLockLed);
587 ASSERT_TRUE(numLockLed);
588 ASSERT_FALSE(scrollLockLed);
589 ASSERT_EQ(AMETA_NUM_LOCK_ON, mMapper->getMetaState());
590
591 // Toggle scroll lock on.
592 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
593 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
594 ASSERT_FALSE(capsLockLed);
595 ASSERT_TRUE(numLockLed);
596 ASSERT_TRUE(scrollLockLed);
597 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mMapper->getMetaState());
598
599 // Toggle num lock off.
600 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1);
601 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0);
602 ASSERT_FALSE(capsLockLed);
603 ASSERT_FALSE(numLockLed);
604 ASSERT_TRUE(scrollLockLed);
605 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mMapper->getMetaState());
606
607 // Toggle scroll lock off.
608 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
609 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
610 ASSERT_FALSE(capsLockLed);
611 ASSERT_FALSE(numLockLed);
612 ASSERT_FALSE(scrollLockLed);
613 ASSERT_EQ(AMETA_NONE, mMapper->getMetaState());
614}
615
616TEST_F(KeyboardInputMapperUnitTest, DisablingDeviceResetsPressedKeys) {
617 const int32_t USAGE_A = 0x070004;
618 addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE);
619 addKeyByUsageCode(USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
620
621 // Key down by scan code.
622 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
623 NotifyKeyArgs args = expectSingleKeyArg(argsList);
624 ASSERT_EQ(DEVICE_ID, args.deviceId);
625 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
626 ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
627 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
628 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
629 ASSERT_EQ(KEY_HOME, args.scanCode);
630 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
631
632 // Disable device, it should synthesize cancellation events for down events.
633 mReaderConfiguration.disabledDevices.insert(DEVICE_ID);
634 argsList = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
635 InputReaderConfiguration::Change::ENABLED_STATE);
636 argsList += mMapper->reset(ARBITRARY_TIME);
637 args = expectSingleKeyArg(argsList);
638 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
639 ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
640 ASSERT_EQ(KEY_HOME, args.scanCode);
641 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
642}
643
644TEST_F(KeyboardInputMapperUnitTest, Configure_AssignKeyboardLayoutInfo) {
645 std::list<NotifyArgs> unused =
646 mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, /*changes=*/{});
647
648 int32_t generation = mDevice->getGeneration();
649 mReaderConfiguration.keyboardLayoutAssociations.insert(
650 {mIdentifier.location, DEVICE_KEYBOARD_LAYOUT_INFO});
651
652 unused += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
653 InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
654
655 InputDeviceInfo deviceInfo;
656 mMapper->populateDeviceInfo(deviceInfo);
657 ASSERT_EQ(DEVICE_KEYBOARD_LAYOUT_INFO.languageTag,
658 deviceInfo.getKeyboardLayoutInfo()->languageTag);
659 ASSERT_EQ(DEVICE_KEYBOARD_LAYOUT_INFO.layoutType,
660 deviceInfo.getKeyboardLayoutInfo()->layoutType);
661 ASSERT_GT(mDevice->getGeneration(), generation);
662
663 // Call change layout association with the same values: Generation shouldn't change
664 generation = mDevice->getGeneration();
665 unused += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
666 InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
667 ASSERT_EQ(mDevice->getGeneration(), generation);
668}
669
670TEST_F(KeyboardInputMapperUnitTest, LayoutInfoCorrectlyMapped) {
671 EXPECT_CALL(mMockEventHub, getRawLayoutInfo(EVENTHUB_ID))
672 .WillRepeatedly(Return(RawLayoutInfo{.languageTag = "en", .layoutType = "extended"}));
673
674 // Configuration
675 std::list<NotifyArgs> unused =
676 mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration, /*changes=*/{});
677
678 InputDeviceInfo deviceInfo;
679 mMapper->populateDeviceInfo(deviceInfo);
680 ASSERT_EQ("en", deviceInfo.getKeyboardLayoutInfo()->languageTag);
681 ASSERT_EQ("extended", deviceInfo.getKeyboardLayoutInfo()->layoutType);
682}
683
684TEST_F(KeyboardInputMapperUnitTest, Process_GestureEventToSetFlagKeepTouchMode) {
685 addKeyByEvdevCode(KEY_LEFT, AKEYCODE_DPAD_LEFT, POLICY_FLAG_GESTURE);
686
687 // Key down
688 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_LEFT, 1);
689 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_KEEP_TOUCH_MODE,
690 expectSingleKeyArg(argsList).flags);
691}
692
693TEST_F_WITH_FLAGS(KeyboardInputMapperUnitTest, WakeBehavior_AlphabeticKeyboard,
694 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
695 enable_alphabetic_keyboard_wake))) {
696 // For internal alphabetic devices, keys will trigger wake on key down.
697
698 addKeyByEvdevCode(KEY_A, AKEYCODE_A);
699 addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME);
700 addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE);
701
702 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_A, 1);
703 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
704
705 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_A, 0);
706 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
707
708 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
709 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
710
711 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
712 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
713
714 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
715 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
716
717 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0);
718 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
719}
Harry Cuttsf673e672024-11-08 17:51:40 +0000720
721// --- KeyboardInputMapperTest ---
722
Harry Cuttsd62330d2024-11-11 13:43:13 +0000723// TODO(b/283812079): convert the tests for this class, which use multiple mappers each, to use
724// InputMapperUnitTest.
Harry Cuttsf673e672024-11-08 17:51:40 +0000725class KeyboardInputMapperTest : public InputMapperTest {
726protected:
727 void SetUp() override {
728 InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::KEYBOARD |
729 InputDeviceClass::ALPHAKEY);
730 }
731 const std::string UNIQUE_ID = "local:0";
Harry Cuttsf673e672024-11-08 17:51:40 +0000732
733 void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode,
734 int32_t originalKeyCode, int32_t rotatedKeyCode,
735 ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID);
736};
737
Harry Cuttsf673e672024-11-08 17:51:40 +0000738void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper,
739 int32_t originalScanCode, int32_t originalKeyCode,
740 int32_t rotatedKeyCode,
741 ui::LogicalDisplayId displayId) {
742 NotifyKeyArgs args;
743
744 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 1);
745 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
746 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
747 ASSERT_EQ(originalScanCode, args.scanCode);
748 ASSERT_EQ(rotatedKeyCode, args.keyCode);
749 ASSERT_EQ(displayId, args.displayId);
750
751 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, originalScanCode, 0);
752 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
753 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
754 ASSERT_EQ(originalScanCode, args.scanCode);
755 ASSERT_EQ(rotatedKeyCode, args.keyCode);
756 ASSERT_EQ(displayId, args.displayId);
757}
758
Harry Cuttsf673e672024-11-08 17:51:40 +0000759TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) {
760 // keyboard 1.
761 mFakeEventHub->addKey(EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
762 mFakeEventHub->addKey(EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
763 mFakeEventHub->addKey(EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
764 mFakeEventHub->addKey(EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
765
766 // keyboard 2.
767 const std::string USB2 = "USB2";
768 const std::string DEVICE_NAME2 = "KEYBOARD2";
769 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
770 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
771 std::shared_ptr<InputDevice> device2 =
772 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
773 ftl::Flags<InputDeviceClass>(0));
774
775 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
776 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
777 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
778 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
779
780 KeyboardInputMapper& mapper =
781 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
782
783 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
784 KeyboardInputMapper& mapper2 =
785 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
786 mFakePolicy
787 ->getReaderConfiguration(),
788 AINPUT_SOURCE_KEYBOARD);
789 std::list<NotifyArgs> unused =
790 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
791 /*changes=*/{});
792 unused += device2->reset(ARBITRARY_TIME);
793
794 // Prepared displays and associated info.
795 constexpr uint8_t hdmi1 = 0;
796 constexpr uint8_t hdmi2 = 1;
797 const std::string SECONDARY_UNIQUE_ID = "local:1";
798
799 mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
800 mFakePolicy->addInputPortAssociation(USB2, hdmi2);
801
802 // No associated display viewport found, should disable the device.
803 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
804 InputReaderConfiguration::Change::DISPLAY_INFO);
805 ASSERT_FALSE(device2->isEnabled());
806
807 // Prepare second display.
808 constexpr ui::LogicalDisplayId newDisplayId = ui::LogicalDisplayId{2};
809 setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
810 UNIQUE_ID, hdmi1, ViewportType::INTERNAL);
811 setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
812 SECONDARY_UNIQUE_ID, hdmi2, ViewportType::EXTERNAL);
813 // Default device will reconfigure above, need additional reconfiguration for another device.
814 unused += device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
815 InputReaderConfiguration::Change::DISPLAY_INFO);
816
817 // Device should be enabled after the associated display is found.
818 ASSERT_TRUE(mDevice->isEnabled());
819 ASSERT_TRUE(device2->isEnabled());
820
821 // Test pad key events
822 ASSERT_NO_FATAL_FAILURE(
823 testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID));
824 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
825 AKEYCODE_DPAD_RIGHT, DISPLAY_ID));
826 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN,
827 AKEYCODE_DPAD_DOWN, DISPLAY_ID));
828 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT,
829 AKEYCODE_DPAD_LEFT, DISPLAY_ID));
830
831 ASSERT_NO_FATAL_FAILURE(
832 testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId));
833 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT,
834 AKEYCODE_DPAD_RIGHT, newDisplayId));
835 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN,
836 AKEYCODE_DPAD_DOWN, newDisplayId));
837 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT,
838 AKEYCODE_DPAD_LEFT, newDisplayId));
839}
840
841TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleAfterReattach) {
842 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
843 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
844 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
845 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
846 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
847 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
848
849 KeyboardInputMapper& mapper =
850 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
851 // Initial metastate is AMETA_NONE.
852 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
853
854 // Initialization should have turned all of the lights off.
855 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
856 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
857 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
858
859 // Toggle caps lock on.
860 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
861 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
862 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
863 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
864
865 // Toggle num lock on.
866 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
867 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
868 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
869 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState());
870
871 // Toggle scroll lock on.
872 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
873 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
874 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
875 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
876
877 mFakeEventHub->removeDevice(EVENTHUB_ID);
878 mReader->loopOnce();
879
880 // keyboard 2 should default toggle keys.
881 const std::string USB2 = "USB2";
882 const std::string DEVICE_NAME2 = "KEYBOARD2";
883 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
884 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
885 std::shared_ptr<InputDevice> device2 =
886 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
887 ftl::Flags<InputDeviceClass>(0));
888 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
889 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
890 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
891 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
892 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
893 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
894
895 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
896 KeyboardInputMapper& mapper2 =
897 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
898 mFakePolicy
899 ->getReaderConfiguration(),
900 AINPUT_SOURCE_KEYBOARD);
901 std::list<NotifyArgs> unused =
902 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
903 /*changes=*/{});
904 unused += device2->reset(ARBITRARY_TIME);
905
906 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
907 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
908 ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
909 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
910 mapper2.getMetaState());
911}
912
913TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) {
914 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
915 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
916 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
917
918 // Suppose we have two mappers. (DPAD + KEYBOARD)
919 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_DPAD);
920 KeyboardInputMapper& mapper =
921 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
922 // Initial metastate is AMETA_NONE.
923 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
924
925 mReader->toggleCapsLockState(DEVICE_ID);
926 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState());
927}
928
Vaibhav Devmurarid3795b52024-11-15 13:46:29 +0000929TEST_F(KeyboardInputMapperTest, Process_ResetLockedModifierState) {
930 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
931 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
932 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
933
934 KeyboardInputMapper& mapper =
935 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
936 // Initial metastate is AMETA_NONE.
937 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
938
939 // Toggle caps lock on.
940 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
941 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
942
943 // Toggle num lock on.
944 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
945 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
946
947 // Toggle scroll lock on.
948 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
949 process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
950 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
951
952 mReader->resetLockedModifierState();
953 ASSERT_EQ(AMETA_NONE, mapper.getMetaState());
954}
955
Harry Cuttsf673e672024-11-08 17:51:40 +0000956TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
957 // keyboard 1.
958 mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
959 mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/);
960 mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
961 mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
962 mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
963 mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
964
965 KeyboardInputMapper& mapper1 =
966 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
967
968 // keyboard 2.
969 const std::string USB2 = "USB2";
970 const std::string DEVICE_NAME2 = "KEYBOARD2";
971 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
972 constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1;
973 std::shared_ptr<InputDevice> device2 =
974 newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID,
975 ftl::Flags<InputDeviceClass>(0));
976 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/);
977 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/);
978 mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/);
979 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
980 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
981 mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
982
983 device2->addEmptyEventHubDevice(SECOND_EVENTHUB_ID);
984 KeyboardInputMapper& mapper2 =
985 device2->constructAndAddMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID,
986 mFakePolicy
987 ->getReaderConfiguration(),
988 AINPUT_SOURCE_KEYBOARD);
989 std::list<NotifyArgs> unused =
990 device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
991 /*changes=*/{});
992 unused += device2->reset(ARBITRARY_TIME);
993
994 // Initial metastate is AMETA_NONE.
995 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
996 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
997
998 // Toggle num lock on and off.
999 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
1000 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
1001 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
1002 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState());
1003 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState());
1004
1005 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1);
1006 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0);
1007 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML));
1008 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
1009 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
1010
1011 // Toggle caps lock on and off.
1012 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
1013 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
1014 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
1015 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState());
1016 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState());
1017
1018 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1);
1019 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0);
1020 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL));
1021 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
1022 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
1023
1024 // Toggle scroll lock on and off.
1025 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
1026 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
1027 ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
1028 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState());
1029 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState());
1030
1031 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
1032 process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
1033 ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL));
1034 ASSERT_EQ(AMETA_NONE, mapper1.getMetaState());
1035 ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
1036}
1037
Harry Cuttsf673e672024-11-08 17:51:40 +00001038/**
1039 * When there is more than one KeyboardInputMapper for an InputDevice, each mapper should produce
1040 * events that use the shared keyboard source across all mappers. This is to ensure that each
1041 * input device generates key events in a consistent manner, regardless of which mapper produces
1042 * the event.
1043 */
1044TEST_F(KeyboardInputMapperTest, UsesSharedKeyboardSource) {
1045 mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
1046
1047 // Add a mapper with SOURCE_KEYBOARD
1048 KeyboardInputMapper& keyboardMapper =
1049 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
1050
1051 process(keyboardMapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1);
1052 ASSERT_NO_FATAL_FAILURE(
1053 mFakeListener->assertNotifyKeyWasCalled(WithSource(AINPUT_SOURCE_KEYBOARD)));
1054 process(keyboardMapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0);
1055 ASSERT_NO_FATAL_FAILURE(
1056 mFakeListener->assertNotifyKeyWasCalled(WithSource(AINPUT_SOURCE_KEYBOARD)));
1057
1058 // Add a mapper with SOURCE_DPAD
1059 KeyboardInputMapper& dpadMapper =
1060 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_DPAD);
1061 for (auto* mapper : {&keyboardMapper, &dpadMapper}) {
1062 process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1);
1063 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
1064 WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD)));
1065 process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0);
1066 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
1067 WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD)));
1068 }
1069
1070 // Add a mapper with SOURCE_GAMEPAD
1071 KeyboardInputMapper& gamepadMapper =
1072 constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_GAMEPAD);
1073 for (auto* mapper : {&keyboardMapper, &dpadMapper, &gamepadMapper}) {
1074 process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1);
1075 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
1076 WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD)));
1077 process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0);
1078 ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
1079 WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD)));
1080 }
1081}
1082
1083// --- KeyboardInputMapperTest_ExternalAlphabeticDevice ---
1084
Harry Cuttsd62330d2024-11-11 13:43:13 +00001085class KeyboardInputMapperTest_ExternalAlphabeticDevice : public KeyboardInputMapperUnitTest {
Harry Cuttsf673e672024-11-08 17:51:40 +00001086protected:
1087 void SetUp() override {
Harry Cuttsd62330d2024-11-11 13:43:13 +00001088 InputMapperUnitTest::SetUp();
1089 ON_CALL((*mDevice), getSources).WillByDefault(Return(AINPUT_SOURCE_KEYBOARD));
1090 ON_CALL((*mDevice), getKeyboardType).WillByDefault(Return(KeyboardType::ALPHABETIC));
1091 ON_CALL((*mDevice), isExternal).WillByDefault(Return(true));
1092 EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
1093 .WillRepeatedly(Return(InputDeviceClass::KEYBOARD | InputDeviceClass::ALPHAKEY |
1094 InputDeviceClass::EXTERNAL));
1095 mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
1096 AINPUT_SOURCE_KEYBOARD);
Harry Cuttsf673e672024-11-08 17:51:40 +00001097 }
1098};
1099
1100// --- KeyboardInputMapperTest_ExternalNonAlphabeticDevice ---
1101
Harry Cuttsd62330d2024-11-11 13:43:13 +00001102class KeyboardInputMapperTest_ExternalNonAlphabeticDevice : public KeyboardInputMapperUnitTest {
Harry Cuttsf673e672024-11-08 17:51:40 +00001103protected:
1104 void SetUp() override {
Harry Cuttsd62330d2024-11-11 13:43:13 +00001105 InputMapperUnitTest::SetUp();
1106 ON_CALL((*mDevice), getSources).WillByDefault(Return(AINPUT_SOURCE_KEYBOARD));
1107 ON_CALL((*mDevice), getKeyboardType).WillByDefault(Return(KeyboardType::NON_ALPHABETIC));
1108 ON_CALL((*mDevice), isExternal).WillByDefault(Return(true));
1109 EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
1110 .WillRepeatedly(Return(InputDeviceClass::KEYBOARD | InputDeviceClass::EXTERNAL));
1111 mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
1112 AINPUT_SOURCE_KEYBOARD);
Harry Cuttsf673e672024-11-08 17:51:40 +00001113 }
1114};
1115
1116TEST_F(KeyboardInputMapperTest_ExternalAlphabeticDevice, WakeBehavior_AlphabeticKeyboard) {
1117 // For external devices, keys will trigger wake on key down. Media keys should also trigger
1118 // wake if triggered from external devices.
1119
Harry Cuttsd62330d2024-11-11 13:43:13 +00001120 addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME);
1121 addKeyByEvdevCode(KEY_PLAY, AKEYCODE_MEDIA_PLAY);
1122 addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE);
Harry Cuttsf673e672024-11-08 17:51:40 +00001123
Harry Cuttsd62330d2024-11-11 13:43:13 +00001124 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
1125 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001126
Harry Cuttsd62330d2024-11-11 13:43:13 +00001127 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
1128 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001129
Harry Cuttsd62330d2024-11-11 13:43:13 +00001130 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1);
1131 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001132
Harry Cuttsd62330d2024-11-11 13:43:13 +00001133 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0);
1134 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001135
Harry Cuttsd62330d2024-11-11 13:43:13 +00001136 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
1137 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001138
Harry Cuttsd62330d2024-11-11 13:43:13 +00001139 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0);
1140 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001141}
1142
1143TEST_F(KeyboardInputMapperTest_ExternalNonAlphabeticDevice, WakeBehavior_NonAlphabeticKeyboard) {
1144 // For external devices, keys will trigger wake on key down. Media keys should not trigger
1145 // wake if triggered from external non-alphaebtic keyboard (e.g. headsets).
1146
Harry Cuttsd62330d2024-11-11 13:43:13 +00001147 addKeyByEvdevCode(KEY_PLAY, AKEYCODE_MEDIA_PLAY);
1148 addKeyByEvdevCode(KEY_PLAYPAUSE, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE);
Harry Cuttsf673e672024-11-08 17:51:40 +00001149
Harry Cuttsd62330d2024-11-11 13:43:13 +00001150 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1);
1151 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001152
Harry Cuttsd62330d2024-11-11 13:43:13 +00001153 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0);
1154 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001155
Harry Cuttsd62330d2024-11-11 13:43:13 +00001156 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAYPAUSE, 1);
1157 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001158
Harry Cuttsd62330d2024-11-11 13:43:13 +00001159 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAYPAUSE, 0);
1160 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001161}
1162
1163TEST_F(KeyboardInputMapperTest_ExternalAlphabeticDevice, DoNotWakeByDefaultBehavior) {
1164 // Tv Remote key's wake behavior is prescribed by the keylayout file.
1165
Harry Cuttsd62330d2024-11-11 13:43:13 +00001166 addKeyByEvdevCode(KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE);
1167 addKeyByEvdevCode(KEY_DOWN, AKEYCODE_DPAD_DOWN);
1168 addKeyByEvdevCode(KEY_PLAY, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE);
Harry Cuttsf673e672024-11-08 17:51:40 +00001169
Harry Cuttsd62330d2024-11-11 13:43:13 +00001170 mPropertyMap.addProperty("keyboard.doNotWakeByDefault", "1");
1171 mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
1172 AINPUT_SOURCE_KEYBOARD);
Harry Cuttsf673e672024-11-08 17:51:40 +00001173
Harry Cuttsd62330d2024-11-11 13:43:13 +00001174 std::list<NotifyArgs> argsList = process(ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
1175 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001176
Harry Cuttsd62330d2024-11-11 13:43:13 +00001177 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
1178 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001179
Harry Cuttsd62330d2024-11-11 13:43:13 +00001180 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_DOWN, 1);
1181 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001182
Harry Cuttsd62330d2024-11-11 13:43:13 +00001183 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_DOWN, 0);
1184 ASSERT_EQ(uint32_t(0), expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001185
Harry Cuttsd62330d2024-11-11 13:43:13 +00001186 argsList = process(ARBITRARY_TIME, EV_KEY, KEY_PLAY, 1);
1187 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001188
Harry Cuttsd62330d2024-11-11 13:43:13 +00001189 argsList = process(ARBITRARY_TIME + 1, EV_KEY, KEY_PLAY, 0);
1190 ASSERT_EQ(POLICY_FLAG_WAKE, expectSingleKeyArg(argsList).policyFlags);
Harry Cuttsf673e672024-11-08 17:51:40 +00001191}
1192
Arpit Singhb3b3f732023-07-04 14:30:05 +00001193} // namespace android