• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.KITKAT;
4 import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
5 
6 import android.view.KeyCharacterMap;
7 import android.view.KeyEvent;
8 import java.util.HashMap;
9 import java.util.Map;
10 import org.robolectric.annotation.Implementation;
11 import org.robolectric.annotation.Implements;
12 import org.robolectric.util.ReflectionHelpers;
13 
14 @Implements(KeyCharacterMap.class)
15 public class ShadowKeyCharacterMap {
16   private static final Map<Character, Integer> CHAR_TO_KEY_CODE = new HashMap<>();
17   private static final Map<Character, Integer> CHAR_TO_KEY_CODE_SHIFT_ON = new HashMap<>();
18 
19   private static final Map<Integer, Character> KEY_CODE_TO_CHAR = new HashMap<>();
20   private static final Map<Integer, Character> KEY_CODE_TO_CHAR_SHIFT_ON = new HashMap<>();
21 
22   static {
23     CHAR_TO_KEY_CODE.put('0', KeyEvent.KEYCODE_0);
24     CHAR_TO_KEY_CODE.put('1', KeyEvent.KEYCODE_1);
25     CHAR_TO_KEY_CODE.put('2', KeyEvent.KEYCODE_2);
26     CHAR_TO_KEY_CODE.put('3', KeyEvent.KEYCODE_3);
27     CHAR_TO_KEY_CODE.put('4', KeyEvent.KEYCODE_4);
28     CHAR_TO_KEY_CODE.put('5', KeyEvent.KEYCODE_5);
29     CHAR_TO_KEY_CODE.put('6', KeyEvent.KEYCODE_6);
30     CHAR_TO_KEY_CODE.put('7', KeyEvent.KEYCODE_7);
31     CHAR_TO_KEY_CODE.put('8', KeyEvent.KEYCODE_8);
32     CHAR_TO_KEY_CODE.put('9', KeyEvent.KEYCODE_9);
33     CHAR_TO_KEY_CODE.put('A', KeyEvent.KEYCODE_A);
34     CHAR_TO_KEY_CODE.put('B', KeyEvent.KEYCODE_B);
35     CHAR_TO_KEY_CODE.put('C', KeyEvent.KEYCODE_C);
36     CHAR_TO_KEY_CODE.put('D', KeyEvent.KEYCODE_D);
37     CHAR_TO_KEY_CODE.put('E', KeyEvent.KEYCODE_E);
38     CHAR_TO_KEY_CODE.put('F', KeyEvent.KEYCODE_F);
39     CHAR_TO_KEY_CODE.put('G', KeyEvent.KEYCODE_G);
40     CHAR_TO_KEY_CODE.put('H', KeyEvent.KEYCODE_H);
41     CHAR_TO_KEY_CODE.put('I', KeyEvent.KEYCODE_I);
42     CHAR_TO_KEY_CODE.put('J', KeyEvent.KEYCODE_J);
43     CHAR_TO_KEY_CODE.put('K', KeyEvent.KEYCODE_K);
44     CHAR_TO_KEY_CODE.put('L', KeyEvent.KEYCODE_L);
45     CHAR_TO_KEY_CODE.put('M', KeyEvent.KEYCODE_M);
46     CHAR_TO_KEY_CODE.put('N', KeyEvent.KEYCODE_N);
47     CHAR_TO_KEY_CODE.put('O', KeyEvent.KEYCODE_O);
48     CHAR_TO_KEY_CODE.put('P', KeyEvent.KEYCODE_P);
49     CHAR_TO_KEY_CODE.put('Q', KeyEvent.KEYCODE_Q);
50     CHAR_TO_KEY_CODE.put('R', KeyEvent.KEYCODE_R);
51     CHAR_TO_KEY_CODE.put('S', KeyEvent.KEYCODE_S);
52     CHAR_TO_KEY_CODE.put('T', KeyEvent.KEYCODE_T);
53     CHAR_TO_KEY_CODE.put('U', KeyEvent.KEYCODE_U);
54     CHAR_TO_KEY_CODE.put('V', KeyEvent.KEYCODE_V);
55     CHAR_TO_KEY_CODE.put('W', KeyEvent.KEYCODE_W);
56     CHAR_TO_KEY_CODE.put('X', KeyEvent.KEYCODE_X);
57     CHAR_TO_KEY_CODE.put('Y', KeyEvent.KEYCODE_Y);
58     CHAR_TO_KEY_CODE.put('Z', KeyEvent.KEYCODE_Z);
59     CHAR_TO_KEY_CODE.put(' ', KeyEvent.KEYCODE_SPACE);
60     CHAR_TO_KEY_CODE.put('-', KeyEvent.KEYCODE_MINUS);
61     CHAR_TO_KEY_CODE.put('+', KeyEvent.KEYCODE_PLUS);
62     CHAR_TO_KEY_CODE.put('@', KeyEvent.KEYCODE_AT);
63     CHAR_TO_KEY_CODE.put('.', KeyEvent.KEYCODE_PERIOD);
64     CHAR_TO_KEY_CODE.put(',', KeyEvent.KEYCODE_COMMA);
65     CHAR_TO_KEY_CODE.put('[', KeyEvent.KEYCODE_LEFT_BRACKET);
66     CHAR_TO_KEY_CODE.put(']', KeyEvent.KEYCODE_RIGHT_BRACKET);
67     CHAR_TO_KEY_CODE.put('\'', KeyEvent.KEYCODE_APOSTROPHE);
68     CHAR_TO_KEY_CODE.put(')', KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN);
69     CHAR_TO_KEY_CODE.put('(', KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN);
70     CHAR_TO_KEY_CODE.put('#', KeyEvent.KEYCODE_POUND);
71     CHAR_TO_KEY_CODE.put('*', KeyEvent.KEYCODE_STAR);
72     CHAR_TO_KEY_CODE.put('/', KeyEvent.KEYCODE_SLASH);
73     CHAR_TO_KEY_CODE.put('=', KeyEvent.KEYCODE_EQUALS);
74     CHAR_TO_KEY_CODE.put('`', KeyEvent.KEYCODE_GRAVE);
75     CHAR_TO_KEY_CODE.put('\\', KeyEvent.KEYCODE_BACKSLASH);
76     CHAR_TO_KEY_CODE.put('\n', KeyEvent.KEYCODE_ENTER);
77 
78     CHAR_TO_KEY_CODE_SHIFT_ON.put('_', KeyEvent.KEYCODE_MINUS);
79     CHAR_TO_KEY_CODE_SHIFT_ON.put('{', KeyEvent.KEYCODE_LEFT_BRACKET);
80     CHAR_TO_KEY_CODE_SHIFT_ON.put('}', KeyEvent.KEYCODE_RIGHT_BRACKET);
81     CHAR_TO_KEY_CODE_SHIFT_ON.put('\"', KeyEvent.KEYCODE_APOSTROPHE);
82     CHAR_TO_KEY_CODE_SHIFT_ON.put('!', KeyEvent.KEYCODE_1);
83     CHAR_TO_KEY_CODE_SHIFT_ON.put('$', KeyEvent.KEYCODE_4);
84     CHAR_TO_KEY_CODE_SHIFT_ON.put('%', KeyEvent.KEYCODE_5);
85     CHAR_TO_KEY_CODE_SHIFT_ON.put('^', KeyEvent.KEYCODE_6);
86     CHAR_TO_KEY_CODE_SHIFT_ON.put('&', KeyEvent.KEYCODE_7);
87     CHAR_TO_KEY_CODE_SHIFT_ON.put('?', KeyEvent.KEYCODE_SLASH);
88     CHAR_TO_KEY_CODE_SHIFT_ON.put('|', KeyEvent.KEYCODE_BACKSLASH);
89     CHAR_TO_KEY_CODE_SHIFT_ON.put('~', KeyEvent.KEYCODE_GRAVE);
90 
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_0, '0')91     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_0, '0');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_1, '1')92     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_1, '1');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_2, '2')93     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_2, '2');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_3, '3')94     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_3, '3');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_4, '4')95     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_4, '4');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_5, '5')96     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_5, '5');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_6, '6')97     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_6, '6');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_7, '7')98     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_7, '7');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_8, '8')99     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_8, '8');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_9, '9')100     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_9, '9');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_A, 'A')101     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_A, 'A');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_B, 'B')102     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_B, 'B');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_C, 'C')103     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_C, 'C');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_D, 'D')104     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_D, 'D');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_E, 'E')105     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_E, 'E');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_F, 'F')106     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_F, 'F');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_G, 'G')107     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_G, 'G');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_H, 'H')108     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_H, 'H');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_I, 'I')109     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_I, 'I');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_J, 'J')110     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_J, 'J');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_K, 'K')111     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_K, 'K');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_L, 'L')112     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_L, 'L');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_M, 'M')113     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_M, 'M');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_N, 'N')114     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_N, 'N');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_O, 'O')115     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_O, 'O');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_P, 'P')116     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_P, 'P');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_Q, 'Q')117     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_Q, 'Q');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_R, 'R')118     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_R, 'R');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_S, 'S')119     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_S, 'S');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_T, 'T')120     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_T, 'T');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_U, 'U')121     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_U, 'U');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_V, 'V')122     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_V, 'V');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_W, 'W')123     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_W, 'W');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_X, 'X')124     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_X, 'X');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_Y, 'Y')125     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_Y, 'Y');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_Z, 'Z')126     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_Z, 'Z');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_SPACE, ' ')127     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_SPACE, ' ');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_MINUS, '-')128     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_MINUS, '-');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_PLUS, '+')129     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_PLUS, '+');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_AT, '@')130     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_AT, '@');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_PERIOD, '.')131     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_PERIOD, '.');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_COMMA, ',')132     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_COMMA, ',');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_LEFT_BRACKET, '[')133     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_LEFT_BRACKET, '[');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_RIGHT_BRACKET, ']')134     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_RIGHT_BRACKET, ']');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_APOSTROPHE, '\\'')135     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_APOSTROPHE, '\'');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN, ')')136     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN, ')');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN, '(')137     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN, '(');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_POUND, '#')138     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_POUND, '#');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_STAR, '*')139     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_STAR, '*');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_SLASH, '/')140     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_SLASH, '/');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_EQUALS, '=')141     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_EQUALS, '=');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_GRAVE, '`')142     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_GRAVE, '`');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_BACKSLASH, '\\\\')143     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_BACKSLASH, '\\');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_ENTER, '\\n')144     KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_ENTER, '\n');
145 
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_MINUS, '_')146     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_MINUS, '_');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_LEFT_BRACKET, '{')147     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_LEFT_BRACKET, '{');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_RIGHT_BRACKET, '}')148     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_RIGHT_BRACKET, '}');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_APOSTROPHE, '\\"')149     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_APOSTROPHE, '\"');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_1, '!')150     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_1, '!');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_4, '$')151     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_4, '$');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_5, '%')152     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_5, '%');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_6, '^')153     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_6, '^');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_7, '&')154     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_7, '&');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_SLASH, '?')155     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_SLASH, '?');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_BACKSLASH, '|')156     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_BACKSLASH, '|');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_GRAVE, '~')157     KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_GRAVE, '~');
158   }
159 
160   @Implementation
load(int deviceId)161   protected static KeyCharacterMap load(int deviceId) {
162     return ReflectionHelpers.callConstructor(KeyCharacterMap.class);
163   }
164 
165   @Implementation
getEvents(char[] chars)166   protected KeyEvent[] getEvents(char[] chars) {
167     if (chars == null) {
168       throw new IllegalArgumentException("chars must not be null.");
169     }
170     int eventsPerChar = 2;
171     KeyEvent[] events = new KeyEvent[chars.length * eventsPerChar];
172 
173     for (int i = 0; i < chars.length; i++) {
174       events[eventsPerChar * i] = getDownEvent(chars[i]);
175       events[eventsPerChar * i + 1] = getUpEvent(chars[i]);
176     }
177 
178     return events;
179   }
180 
181   @Implementation
getKeyboardType()182   protected int getKeyboardType() {
183     return KeyCharacterMap.FULL;
184   }
185 
186   @Implementation
get(int keyCode, int metaState)187   protected int get(int keyCode, int metaState) {
188     boolean metaShiftOn = (metaState & KeyEvent.META_SHIFT_ON) != 0;
189     Character character = KEY_CODE_TO_CHAR.get(keyCode);
190     if (character == null) {
191       return 0;
192     } else if (metaShiftOn) {
193       return KEY_CODE_TO_CHAR_SHIFT_ON.getOrDefault(keyCode, character);
194     } else {
195       return Character.toLowerCase(character);
196     }
197   }
198 
getDownEvent(char a)199   public KeyEvent getDownEvent(char a) {
200     return new KeyEvent(
201         0,
202         0,
203         KeyEvent.ACTION_DOWN,
204         toCharKeyCode(a),
205         0,
206         getMetaState(a),
207         KeyCharacterMap.VIRTUAL_KEYBOARD,
208         0);
209   }
210 
getUpEvent(char a)211   public KeyEvent getUpEvent(char a) {
212     return new KeyEvent(
213         0,
214         0,
215         KeyEvent.ACTION_UP,
216         toCharKeyCode(a),
217         0,
218         getMetaState(a),
219         KeyCharacterMap.VIRTUAL_KEYBOARD,
220         0);
221   }
222 
223   @Implementation
getDisplayLabel(int keyCode)224   protected char getDisplayLabel(int keyCode) {
225     return KEY_CODE_TO_CHAR.getOrDefault(keyCode, (char) 0);
226   }
227 
228   @Implementation
isPrintingKey(int keyCode)229   protected boolean isPrintingKey(int keyCode) {
230     int type = Character.getType(getDisplayLabel(keyCode));
231     switch (type) {
232       case Character.SPACE_SEPARATOR:
233       case Character.LINE_SEPARATOR:
234       case Character.PARAGRAPH_SEPARATOR:
235       case Character.CONTROL:
236       case Character.FORMAT:
237         return false;
238       default:
239         return true;
240     }
241   }
242 
243   @Implementation(minSdk = KITKAT_WATCH)
nativeGetNumber(long ptr, int keyCode)244   protected static char nativeGetNumber(long ptr, int keyCode) {
245     Character character = KEY_CODE_TO_CHAR.get(keyCode);
246     if (character == null) {
247       return 0;
248     }
249     return character;
250   }
251 
252   @Implementation(maxSdk = KITKAT)
nativeGetNumber(int ptr, int keyCode)253   protected static char nativeGetNumber(int ptr, int keyCode) {
254     Character character = KEY_CODE_TO_CHAR.get(keyCode);
255     if (character == null) {
256       return 0;
257     }
258     return character;
259   }
260 
toCharKeyCode(char a)261   private int toCharKeyCode(char a) {
262     if (CHAR_TO_KEY_CODE.containsKey(Character.toUpperCase(a))) {
263       return CHAR_TO_KEY_CODE.get(Character.toUpperCase(a));
264     } else if (CHAR_TO_KEY_CODE_SHIFT_ON.containsKey(a)) {
265       return CHAR_TO_KEY_CODE_SHIFT_ON.get(a);
266     } else {
267       return 0;
268     }
269   }
270 
getMetaState(char a)271   private int getMetaState(char a) {
272     if (Character.isUpperCase(a) || CHAR_TO_KEY_CODE_SHIFT_ON.containsKey(a)) {
273       return KeyEvent.META_SHIFT_ON;
274     } else {
275       return 0;
276     }
277   }
278 }
279