1 /*
2  * Copyright 2024 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 #define LOG_TAG "KeyboardClassifier"
18 
19 #include <android-base/logging.h>
20 #include <com_android_input_flags.h>
21 #include <ftl/flags.h>
22 #include <input/KeyboardClassifier.h>
23 
24 #include "input_cxx_bridge.rs.h"
25 
26 namespace input_flags = com::android::input::flags;
27 
28 using android::input::RustInputDeviceIdentifier;
29 
30 namespace android {
31 
KeyboardClassifier()32 KeyboardClassifier::KeyboardClassifier() {
33     if (input_flags::enable_keyboard_classifier()) {
34         mRustClassifier = android::input::keyboardClassifier::create();
35     }
36 }
37 
getKeyboardType(DeviceId deviceId)38 KeyboardType KeyboardClassifier::getKeyboardType(DeviceId deviceId) {
39     if (mRustClassifier) {
40         return static_cast<KeyboardType>(
41                 android::input::keyboardClassifier::getKeyboardType(**mRustClassifier, deviceId));
42     } else {
43         auto it = mKeyboardTypeMap.find(deviceId);
44         if (it == mKeyboardTypeMap.end()) {
45             return KeyboardType::NONE;
46         }
47         return it->second;
48     }
49 }
50 
51 // Copied from EventHub.h
52 const uint32_t DEVICE_CLASS_KEYBOARD = android::os::IInputConstants::DEVICE_CLASS_KEYBOARD;
53 const uint32_t DEVICE_CLASS_ALPHAKEY = android::os::IInputConstants::DEVICE_CLASS_ALPHAKEY;
54 
notifyKeyboardChanged(DeviceId deviceId,const InputDeviceIdentifier & identifier,uint32_t deviceClasses)55 void KeyboardClassifier::notifyKeyboardChanged(DeviceId deviceId,
56                                                const InputDeviceIdentifier& identifier,
57                                                uint32_t deviceClasses) {
58     if (mRustClassifier) {
59         RustInputDeviceIdentifier rustIdentifier;
60         rustIdentifier.name = identifier.name;
61         rustIdentifier.location = identifier.location;
62         rustIdentifier.unique_id = identifier.uniqueId;
63         rustIdentifier.bus = identifier.bus;
64         rustIdentifier.vendor = identifier.vendor;
65         rustIdentifier.product = identifier.product;
66         rustIdentifier.version = identifier.version;
67         rustIdentifier.descriptor = identifier.descriptor;
68         android::input::keyboardClassifier::notifyKeyboardChanged(**mRustClassifier, deviceId,
69                                                                   rustIdentifier, deviceClasses);
70     } else {
71         bool isKeyboard = (deviceClasses & DEVICE_CLASS_KEYBOARD) != 0;
72         bool hasAlphabeticKey = (deviceClasses & DEVICE_CLASS_ALPHAKEY) != 0;
73         mKeyboardTypeMap.insert_or_assign(deviceId,
74                                           isKeyboard ? (hasAlphabeticKey
75                                                                 ? KeyboardType::ALPHABETIC
76                                                                 : KeyboardType::NON_ALPHABETIC)
77                                                      : KeyboardType::NONE);
78     }
79 }
80 
processKey(DeviceId deviceId,int32_t evdevCode,uint32_t metaState)81 void KeyboardClassifier::processKey(DeviceId deviceId, int32_t evdevCode, uint32_t metaState) {
82     if (mRustClassifier &&
83         !android::input::keyboardClassifier::isFinalized(**mRustClassifier, deviceId)) {
84         android::input::keyboardClassifier::processKey(**mRustClassifier, deviceId, evdevCode,
85                                                        metaState);
86     }
87 }
88 
89 } // namespace android
90