1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2010 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "Keyboard"
18*38e8c45fSAndroid Build Coastguard Worker
19*38e8c45fSAndroid Build Coastguard Worker #include <limits.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <optional>
23*38e8c45fSAndroid Build Coastguard Worker
24*38e8c45fSAndroid Build Coastguard Worker #include <input/InputDevice.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <input/InputEventLabels.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <input/KeyCharacterMap.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <input/KeyLayoutMap.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <input/Keyboard.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <utils/Errors.h>
31*38e8c45fSAndroid Build Coastguard Worker
32*38e8c45fSAndroid Build Coastguard Worker namespace android {
33*38e8c45fSAndroid Build Coastguard Worker
getPath(const InputDeviceIdentifier & deviceIdentifier,const std::string & name,InputDeviceConfigurationFileType type)34*38e8c45fSAndroid Build Coastguard Worker static std::string getPath(const InputDeviceIdentifier& deviceIdentifier, const std::string& name,
35*38e8c45fSAndroid Build Coastguard Worker InputDeviceConfigurationFileType type) {
36*38e8c45fSAndroid Build Coastguard Worker return name.empty()
37*38e8c45fSAndroid Build Coastguard Worker ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
38*38e8c45fSAndroid Build Coastguard Worker : getInputDeviceConfigurationFilePathByName(name, type);
39*38e8c45fSAndroid Build Coastguard Worker }
40*38e8c45fSAndroid Build Coastguard Worker
41*38e8c45fSAndroid Build Coastguard Worker // --- KeyMap ---
42*38e8c45fSAndroid Build Coastguard Worker
KeyMap()43*38e8c45fSAndroid Build Coastguard Worker KeyMap::KeyMap() {
44*38e8c45fSAndroid Build Coastguard Worker }
45*38e8c45fSAndroid Build Coastguard Worker
~KeyMap()46*38e8c45fSAndroid Build Coastguard Worker KeyMap::~KeyMap() {
47*38e8c45fSAndroid Build Coastguard Worker }
48*38e8c45fSAndroid Build Coastguard Worker
load(const InputDeviceIdentifier & deviceIdentifier,const PropertyMap * deviceConfiguration)49*38e8c45fSAndroid Build Coastguard Worker status_t KeyMap::load(const InputDeviceIdentifier& deviceIdentifier,
50*38e8c45fSAndroid Build Coastguard Worker const PropertyMap* deviceConfiguration) {
51*38e8c45fSAndroid Build Coastguard Worker // Use the configured key layout if available.
52*38e8c45fSAndroid Build Coastguard Worker if (deviceConfiguration) {
53*38e8c45fSAndroid Build Coastguard Worker std::optional<std::string> keyLayoutName =
54*38e8c45fSAndroid Build Coastguard Worker deviceConfiguration->getString("keyboard.layout");
55*38e8c45fSAndroid Build Coastguard Worker if (keyLayoutName.has_value()) {
56*38e8c45fSAndroid Build Coastguard Worker status_t status = loadKeyLayout(deviceIdentifier, *keyLayoutName);
57*38e8c45fSAndroid Build Coastguard Worker if (status == NAME_NOT_FOUND) {
58*38e8c45fSAndroid Build Coastguard Worker ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
59*38e8c45fSAndroid Build Coastguard Worker "it was not found.",
60*38e8c45fSAndroid Build Coastguard Worker deviceIdentifier.name.c_str(), keyLayoutName->c_str());
61*38e8c45fSAndroid Build Coastguard Worker }
62*38e8c45fSAndroid Build Coastguard Worker }
63*38e8c45fSAndroid Build Coastguard Worker
64*38e8c45fSAndroid Build Coastguard Worker std::optional<std::string> keyCharacterMapName =
65*38e8c45fSAndroid Build Coastguard Worker deviceConfiguration->getString("keyboard.characterMap");
66*38e8c45fSAndroid Build Coastguard Worker if (keyCharacterMapName.has_value()) {
67*38e8c45fSAndroid Build Coastguard Worker status_t status = loadKeyCharacterMap(deviceIdentifier, *keyCharacterMapName);
68*38e8c45fSAndroid Build Coastguard Worker if (status == NAME_NOT_FOUND) {
69*38e8c45fSAndroid Build Coastguard Worker ALOGE("Configuration for keyboard device '%s' requested keyboard character "
70*38e8c45fSAndroid Build Coastguard Worker "map '%s' but it was not found.",
71*38e8c45fSAndroid Build Coastguard Worker deviceIdentifier.name.c_str(), keyCharacterMapName->c_str());
72*38e8c45fSAndroid Build Coastguard Worker }
73*38e8c45fSAndroid Build Coastguard Worker }
74*38e8c45fSAndroid Build Coastguard Worker
75*38e8c45fSAndroid Build Coastguard Worker if (isComplete()) {
76*38e8c45fSAndroid Build Coastguard Worker return OK;
77*38e8c45fSAndroid Build Coastguard Worker }
78*38e8c45fSAndroid Build Coastguard Worker }
79*38e8c45fSAndroid Build Coastguard Worker
80*38e8c45fSAndroid Build Coastguard Worker // Try searching by device identifier.
81*38e8c45fSAndroid Build Coastguard Worker if (probeKeyMap(deviceIdentifier, "")) {
82*38e8c45fSAndroid Build Coastguard Worker return OK;
83*38e8c45fSAndroid Build Coastguard Worker }
84*38e8c45fSAndroid Build Coastguard Worker
85*38e8c45fSAndroid Build Coastguard Worker // Fall back on the Generic key map.
86*38e8c45fSAndroid Build Coastguard Worker // TODO Apply some additional heuristics here to figure out what kind of
87*38e8c45fSAndroid Build Coastguard Worker // generic key map to use (US English, etc.) for typical external keyboards.
88*38e8c45fSAndroid Build Coastguard Worker if (probeKeyMap(deviceIdentifier, "Generic")) {
89*38e8c45fSAndroid Build Coastguard Worker return OK;
90*38e8c45fSAndroid Build Coastguard Worker }
91*38e8c45fSAndroid Build Coastguard Worker
92*38e8c45fSAndroid Build Coastguard Worker // Try the Virtual key map as a last resort.
93*38e8c45fSAndroid Build Coastguard Worker if (probeKeyMap(deviceIdentifier, "Virtual")) {
94*38e8c45fSAndroid Build Coastguard Worker return OK;
95*38e8c45fSAndroid Build Coastguard Worker }
96*38e8c45fSAndroid Build Coastguard Worker
97*38e8c45fSAndroid Build Coastguard Worker // Give up!
98*38e8c45fSAndroid Build Coastguard Worker ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
99*38e8c45fSAndroid Build Coastguard Worker deviceIdentifier.name.c_str());
100*38e8c45fSAndroid Build Coastguard Worker return NAME_NOT_FOUND;
101*38e8c45fSAndroid Build Coastguard Worker }
102*38e8c45fSAndroid Build Coastguard Worker
probeKeyMap(const InputDeviceIdentifier & deviceIdentifier,const std::string & keyMapName)103*38e8c45fSAndroid Build Coastguard Worker bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
104*38e8c45fSAndroid Build Coastguard Worker const std::string& keyMapName) {
105*38e8c45fSAndroid Build Coastguard Worker if (!haveKeyLayout()) {
106*38e8c45fSAndroid Build Coastguard Worker loadKeyLayout(deviceIdentifier, keyMapName);
107*38e8c45fSAndroid Build Coastguard Worker }
108*38e8c45fSAndroid Build Coastguard Worker if (!haveKeyCharacterMap()) {
109*38e8c45fSAndroid Build Coastguard Worker loadKeyCharacterMap(deviceIdentifier, keyMapName);
110*38e8c45fSAndroid Build Coastguard Worker }
111*38e8c45fSAndroid Build Coastguard Worker return isComplete();
112*38e8c45fSAndroid Build Coastguard Worker }
113*38e8c45fSAndroid Build Coastguard Worker
loadKeyLayout(const InputDeviceIdentifier & deviceIdentifier,const std::string & name)114*38e8c45fSAndroid Build Coastguard Worker status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
115*38e8c45fSAndroid Build Coastguard Worker const std::string& name) {
116*38e8c45fSAndroid Build Coastguard Worker std::string path(getPath(deviceIdentifier, name, InputDeviceConfigurationFileType::KEY_LAYOUT));
117*38e8c45fSAndroid Build Coastguard Worker if (path.empty()) {
118*38e8c45fSAndroid Build Coastguard Worker return NAME_NOT_FOUND;
119*38e8c45fSAndroid Build Coastguard Worker }
120*38e8c45fSAndroid Build Coastguard Worker
121*38e8c45fSAndroid Build Coastguard Worker base::Result<std::shared_ptr<KeyLayoutMap>> ret = KeyLayoutMap::load(path);
122*38e8c45fSAndroid Build Coastguard Worker if (ret.ok()) {
123*38e8c45fSAndroid Build Coastguard Worker keyLayoutMap = *ret;
124*38e8c45fSAndroid Build Coastguard Worker keyLayoutFile = path;
125*38e8c45fSAndroid Build Coastguard Worker return OK;
126*38e8c45fSAndroid Build Coastguard Worker }
127*38e8c45fSAndroid Build Coastguard Worker
128*38e8c45fSAndroid Build Coastguard Worker // Try to load fallback layout if the regular layout could not be loaded due to missing
129*38e8c45fSAndroid Build Coastguard Worker // kernel modules
130*38e8c45fSAndroid Build Coastguard Worker std::string fallbackPath(
131*38e8c45fSAndroid Build Coastguard Worker getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier,
132*38e8c45fSAndroid Build Coastguard Worker InputDeviceConfigurationFileType::
133*38e8c45fSAndroid Build Coastguard Worker KEY_LAYOUT,
134*38e8c45fSAndroid Build Coastguard Worker "_fallback"));
135*38e8c45fSAndroid Build Coastguard Worker ret = KeyLayoutMap::load(fallbackPath);
136*38e8c45fSAndroid Build Coastguard Worker if (!ret.ok()) {
137*38e8c45fSAndroid Build Coastguard Worker return ret.error().code();
138*38e8c45fSAndroid Build Coastguard Worker }
139*38e8c45fSAndroid Build Coastguard Worker keyLayoutMap = *ret;
140*38e8c45fSAndroid Build Coastguard Worker keyLayoutFile = fallbackPath;
141*38e8c45fSAndroid Build Coastguard Worker return OK;
142*38e8c45fSAndroid Build Coastguard Worker }
143*38e8c45fSAndroid Build Coastguard Worker
loadKeyCharacterMap(const InputDeviceIdentifier & deviceIdentifier,const std::string & name)144*38e8c45fSAndroid Build Coastguard Worker status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
145*38e8c45fSAndroid Build Coastguard Worker const std::string& name) {
146*38e8c45fSAndroid Build Coastguard Worker std::string path =
147*38e8c45fSAndroid Build Coastguard Worker getPath(deviceIdentifier, name, InputDeviceConfigurationFileType::KEY_CHARACTER_MAP);
148*38e8c45fSAndroid Build Coastguard Worker if (path.empty()) {
149*38e8c45fSAndroid Build Coastguard Worker return NAME_NOT_FOUND;
150*38e8c45fSAndroid Build Coastguard Worker }
151*38e8c45fSAndroid Build Coastguard Worker
152*38e8c45fSAndroid Build Coastguard Worker base::Result<std::shared_ptr<KeyCharacterMap>> ret =
153*38e8c45fSAndroid Build Coastguard Worker KeyCharacterMap::load(path, KeyCharacterMap::Format::BASE);
154*38e8c45fSAndroid Build Coastguard Worker if (!ret.ok()) {
155*38e8c45fSAndroid Build Coastguard Worker return ret.error().code();
156*38e8c45fSAndroid Build Coastguard Worker }
157*38e8c45fSAndroid Build Coastguard Worker keyCharacterMap = *ret;
158*38e8c45fSAndroid Build Coastguard Worker keyCharacterMapFile = path;
159*38e8c45fSAndroid Build Coastguard Worker return OK;
160*38e8c45fSAndroid Build Coastguard Worker }
161*38e8c45fSAndroid Build Coastguard Worker
162*38e8c45fSAndroid Build Coastguard Worker // --- Global functions ---
163*38e8c45fSAndroid Build Coastguard Worker
isKeyboardSpecialFunction(const PropertyMap * config)164*38e8c45fSAndroid Build Coastguard Worker bool isKeyboardSpecialFunction(const PropertyMap* config) {
165*38e8c45fSAndroid Build Coastguard Worker if (config == nullptr) {
166*38e8c45fSAndroid Build Coastguard Worker return false;
167*38e8c45fSAndroid Build Coastguard Worker }
168*38e8c45fSAndroid Build Coastguard Worker return config->getBool("keyboard.specialFunction").value_or(false);
169*38e8c45fSAndroid Build Coastguard Worker }
170*38e8c45fSAndroid Build Coastguard Worker
isEligibleBuiltInKeyboard(const InputDeviceIdentifier & deviceIdentifier,const PropertyMap * deviceConfiguration,const KeyMap * keyMap)171*38e8c45fSAndroid Build Coastguard Worker bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
172*38e8c45fSAndroid Build Coastguard Worker const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
173*38e8c45fSAndroid Build Coastguard Worker // TODO: remove the third OR statement (SPECIAL_FUNCTION) in Q
174*38e8c45fSAndroid Build Coastguard Worker if (!keyMap->haveKeyCharacterMap() || isKeyboardSpecialFunction(deviceConfiguration) ||
175*38e8c45fSAndroid Build Coastguard Worker keyMap->keyCharacterMap->getKeyboardType() ==
176*38e8c45fSAndroid Build Coastguard Worker KeyCharacterMap::KeyboardType::SPECIAL_FUNCTION) {
177*38e8c45fSAndroid Build Coastguard Worker return false;
178*38e8c45fSAndroid Build Coastguard Worker }
179*38e8c45fSAndroid Build Coastguard Worker
180*38e8c45fSAndroid Build Coastguard Worker if (deviceConfiguration) {
181*38e8c45fSAndroid Build Coastguard Worker if (deviceConfiguration->getBool("keyboard.builtIn").value_or(false)) {
182*38e8c45fSAndroid Build Coastguard Worker return true;
183*38e8c45fSAndroid Build Coastguard Worker }
184*38e8c45fSAndroid Build Coastguard Worker }
185*38e8c45fSAndroid Build Coastguard Worker
186*38e8c45fSAndroid Build Coastguard Worker return strstr(deviceIdentifier.name.c_str(), "-keypad");
187*38e8c45fSAndroid Build Coastguard Worker }
188*38e8c45fSAndroid Build Coastguard Worker
setEphemeralMetaState(int32_t mask,bool down,int32_t oldMetaState)189*38e8c45fSAndroid Build Coastguard Worker static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
190*38e8c45fSAndroid Build Coastguard Worker int32_t newMetaState;
191*38e8c45fSAndroid Build Coastguard Worker if (down) {
192*38e8c45fSAndroid Build Coastguard Worker newMetaState = oldMetaState | mask;
193*38e8c45fSAndroid Build Coastguard Worker } else {
194*38e8c45fSAndroid Build Coastguard Worker newMetaState = oldMetaState &
195*38e8c45fSAndroid Build Coastguard Worker ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
196*38e8c45fSAndroid Build Coastguard Worker }
197*38e8c45fSAndroid Build Coastguard Worker
198*38e8c45fSAndroid Build Coastguard Worker return normalizeMetaState(newMetaState);
199*38e8c45fSAndroid Build Coastguard Worker }
200*38e8c45fSAndroid Build Coastguard Worker
normalizeMetaState(int32_t oldMetaState)201*38e8c45fSAndroid Build Coastguard Worker int32_t normalizeMetaState(int32_t oldMetaState) {
202*38e8c45fSAndroid Build Coastguard Worker int32_t newMetaState = oldMetaState;
203*38e8c45fSAndroid Build Coastguard Worker if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
204*38e8c45fSAndroid Build Coastguard Worker newMetaState |= AMETA_ALT_ON;
205*38e8c45fSAndroid Build Coastguard Worker }
206*38e8c45fSAndroid Build Coastguard Worker
207*38e8c45fSAndroid Build Coastguard Worker if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
208*38e8c45fSAndroid Build Coastguard Worker newMetaState |= AMETA_SHIFT_ON;
209*38e8c45fSAndroid Build Coastguard Worker }
210*38e8c45fSAndroid Build Coastguard Worker
211*38e8c45fSAndroid Build Coastguard Worker if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
212*38e8c45fSAndroid Build Coastguard Worker newMetaState |= AMETA_CTRL_ON;
213*38e8c45fSAndroid Build Coastguard Worker }
214*38e8c45fSAndroid Build Coastguard Worker
215*38e8c45fSAndroid Build Coastguard Worker if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
216*38e8c45fSAndroid Build Coastguard Worker newMetaState |= AMETA_META_ON;
217*38e8c45fSAndroid Build Coastguard Worker }
218*38e8c45fSAndroid Build Coastguard Worker return newMetaState;
219*38e8c45fSAndroid Build Coastguard Worker }
220*38e8c45fSAndroid Build Coastguard Worker
toggleLockedMetaState(int32_t mask,bool down,int32_t oldMetaState)221*38e8c45fSAndroid Build Coastguard Worker static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
222*38e8c45fSAndroid Build Coastguard Worker if (down) {
223*38e8c45fSAndroid Build Coastguard Worker return oldMetaState;
224*38e8c45fSAndroid Build Coastguard Worker } else {
225*38e8c45fSAndroid Build Coastguard Worker return oldMetaState ^ mask;
226*38e8c45fSAndroid Build Coastguard Worker }
227*38e8c45fSAndroid Build Coastguard Worker }
228*38e8c45fSAndroid Build Coastguard Worker
updateMetaState(int32_t keyCode,bool down,int32_t oldMetaState)229*38e8c45fSAndroid Build Coastguard Worker int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
230*38e8c45fSAndroid Build Coastguard Worker switch (keyCode) {
231*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_ALT_LEFT:
232*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
233*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_ALT_RIGHT:
234*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
235*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SHIFT_LEFT:
236*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
237*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SHIFT_RIGHT:
238*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
239*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SYM:
240*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
241*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_FUNCTION:
242*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
243*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_CTRL_LEFT:
244*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
245*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_CTRL_RIGHT:
246*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
247*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_META_LEFT:
248*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
249*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_META_RIGHT:
250*38e8c45fSAndroid Build Coastguard Worker return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
251*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_CAPS_LOCK:
252*38e8c45fSAndroid Build Coastguard Worker return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
253*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_NUM_LOCK:
254*38e8c45fSAndroid Build Coastguard Worker return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
255*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SCROLL_LOCK:
256*38e8c45fSAndroid Build Coastguard Worker return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
257*38e8c45fSAndroid Build Coastguard Worker default:
258*38e8c45fSAndroid Build Coastguard Worker return oldMetaState;
259*38e8c45fSAndroid Build Coastguard Worker }
260*38e8c45fSAndroid Build Coastguard Worker }
261*38e8c45fSAndroid Build Coastguard Worker
isMetaKey(int32_t keyCode)262*38e8c45fSAndroid Build Coastguard Worker bool isMetaKey(int32_t keyCode) {
263*38e8c45fSAndroid Build Coastguard Worker switch (keyCode) {
264*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_ALT_LEFT:
265*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_ALT_RIGHT:
266*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SHIFT_LEFT:
267*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SHIFT_RIGHT:
268*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SYM:
269*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_FUNCTION:
270*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_CTRL_LEFT:
271*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_CTRL_RIGHT:
272*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_META_LEFT:
273*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_META_RIGHT:
274*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_CAPS_LOCK:
275*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_NUM_LOCK:
276*38e8c45fSAndroid Build Coastguard Worker case AKEYCODE_SCROLL_LOCK:
277*38e8c45fSAndroid Build Coastguard Worker return true;
278*38e8c45fSAndroid Build Coastguard Worker default:
279*38e8c45fSAndroid Build Coastguard Worker return false;
280*38e8c45fSAndroid Build Coastguard Worker }
281*38e8c45fSAndroid Build Coastguard Worker }
282*38e8c45fSAndroid Build Coastguard Worker
283*38e8c45fSAndroid Build Coastguard Worker
284*38e8c45fSAndroid Build Coastguard Worker } // namespace android
285