1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.apps.inputmethod.simpleime; 18 19 import android.text.TextUtils; 20 import android.util.Log; 21 import android.util.SparseArray; 22 import android.view.KeyEvent; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.TextView; 27 28 /** Controls the visible virtual keyboard view. */ 29 final class SimpleKeyboard { 30 private static final String TAG = "SimpleKeyboard"; 31 32 private static final int[] SOFT_KEY_IDS = 33 new int[] { 34 R.id.key_pos_0_0, 35 R.id.key_pos_0_1, 36 R.id.key_pos_0_2, 37 R.id.key_pos_0_3, 38 R.id.key_pos_0_4, 39 R.id.key_pos_0_5, 40 R.id.key_pos_0_6, 41 R.id.key_pos_0_7, 42 R.id.key_pos_0_8, 43 R.id.key_pos_0_9, 44 R.id.key_pos_1_0, 45 R.id.key_pos_1_1, 46 R.id.key_pos_1_2, 47 R.id.key_pos_1_3, 48 R.id.key_pos_1_4, 49 R.id.key_pos_1_5, 50 R.id.key_pos_1_6, 51 R.id.key_pos_1_7, 52 R.id.key_pos_1_8, 53 R.id.key_pos_2_0, 54 R.id.key_pos_2_1, 55 R.id.key_pos_2_2, 56 R.id.key_pos_2_3, 57 R.id.key_pos_2_4, 58 R.id.key_pos_2_5, 59 R.id.key_pos_2_6, 60 R.id.key_pos_shift, 61 R.id.key_pos_del, 62 R.id.key_pos_symbol, 63 R.id.key_pos_comma, 64 R.id.key_pos_space, 65 R.id.key_pos_period, 66 R.id.key_pos_enter, 67 }; 68 69 private final SimpleInputMethodService mSimpleInputMethodService; 70 private final int mViewResId; 71 private final SparseArray<TextView> mSoftKeyViews = new SparseArray<>(); 72 private View mKeyboardView; 73 private int mKeyboardState; 74 SimpleKeyboard(SimpleInputMethodService simpleInputMethodService, int viewResId)75 SimpleKeyboard(SimpleInputMethodService simpleInputMethodService, int viewResId) { 76 this.mSimpleInputMethodService = simpleInputMethodService; 77 this.mViewResId = viewResId; 78 this.mKeyboardState = 0; 79 } 80 inflateKeyboardView(LayoutInflater inflater, ViewGroup inputView)81 View inflateKeyboardView(LayoutInflater inflater, ViewGroup inputView) { 82 mKeyboardView = inflater.inflate(mViewResId, inputView, false); 83 mapSoftKeys(); 84 return mKeyboardView; 85 } 86 mapSoftKeys()87 private void mapSoftKeys() { 88 for (int id : SOFT_KEY_IDS) { 89 TextView softKeyView = mKeyboardView.findViewById(id); 90 mSoftKeyViews.put(id, softKeyView); 91 String tagData = softKeyView.getTag() != null ? softKeyView.getTag().toString() : null; 92 softKeyView.setOnClickListener(v -> handle(tagData)); 93 } 94 } 95 handle(String data)96 private void handle(String data) { 97 Log.i(TAG, "handle(): " + data); 98 if (TextUtils.isEmpty(data)) { 99 return; 100 } 101 if ("KEYCODE_SHIFT".equals(data)) { 102 handleShift(); 103 return; 104 } 105 106 mSimpleInputMethodService.handle(data, mKeyboardState); 107 } 108 handleShift()109 private void handleShift() { 110 mKeyboardState = toggleShiftState(mKeyboardState); 111 Log.v(TAG, "currentKeyboardState: " + mKeyboardState); 112 boolean isShiftOn = isShiftOn(mKeyboardState); 113 for (int i = 0; i < mSoftKeyViews.size(); i++) { 114 TextView softKeyView = mSoftKeyViews.valueAt(i); 115 softKeyView.setAllCaps(isShiftOn); 116 } 117 } 118 isShiftOn(int state)119 private static boolean isShiftOn(int state) { 120 return (state & KeyEvent.META_SHIFT_ON) == KeyEvent.META_SHIFT_ON; 121 } 122 toggleShiftState(int state)123 private static int toggleShiftState(int state) { 124 return state ^ KeyEvent.META_SHIFT_ON; 125 } 126 } 127