1b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer/* 2b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * Copyright (C) 2016 The Android Open Source Project 3b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * 4b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License"); 5b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * you may not use this file except in compliance with the License. 6b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * You may obtain a copy of the License at 7b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * 8b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * http://www.apache.org/licenses/LICENSE-2.0 9b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * 10b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * Unless required by applicable law or agreed to in writing, software 11b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS, 12b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * See the License for the specific language governing permissions and 14b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * limitations under the License. 15b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer */ 16b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerpackage com.android.inputmethod.latin; 17b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 184db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadiimport android.car.Car; 19b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.car.CarNotConnectedException; 204db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadiimport android.car.drivingstate.CarUxRestrictions; 214db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadiimport android.car.drivingstate.CarUxRestrictionsManager; 22b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.content.ComponentName; 23b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.content.ServiceConnection; 24b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.content.res.Configuration; 25b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.content.res.Resources; 26b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.inputmethodservice.InputMethodService; 27b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.inputmethodservice.Keyboard; 28b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.os.Handler; 29b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.os.IBinder; 30b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.os.Message; 31b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.text.TextUtils; 32b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.util.Log; 33b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.view.LayoutInflater; 34b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.view.View; 35b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.view.inputmethod.EditorInfo; 36b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.view.inputmethod.InputConnection; 37b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport android.widget.FrameLayout; 38b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 39b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport com.android.inputmethod.latin.car.KeyboardView; 40b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 41b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport java.lang.ref.WeakReference; 42b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport java.util.Locale; 43b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 44b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerimport javax.annotation.concurrent.GuardedBy; 45b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 46b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer/** 47b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * IME for car use case. 2 features are added compared to the original IME. 48b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * <ul> 494db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi * <li> Monitor driving status, and put a lockout screen on top of the current keyboard if 504db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi * keyboard input is not allowed. 514db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi * <li> Add a close keyboard button so that user dismiss the keyboard when "back" button is not 524db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi * present in the system navigation bar. 53b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * </ul> 54b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer */ 55b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyerpublic class CarLatinIME extends InputMethodService { 56b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final String TAG = "CarLatinIME"; 57b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final String DEFAULT_LANGUAGE = "en"; 58b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final String LAYOUT_XML = "input_keyboard_layout"; 59b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final String SYMBOL_LAYOUT_XML = "input_keyboard_layout_symbol"; 60b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 6160ee7843f916e9860d14a627734367ef6983566brleix private static final int KEYCODE_ENTER = '\n'; 6260ee7843f916e9860d14a627734367ef6983566brleix private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1; 63b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final int MSG_ENABLE_KEYBOARD = 0; 64b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final int KEYCODE_CYCLE_CHAR = -7; 65b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final int KEYCODE_MAIN_KEYBOARD = -8; 66b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final int KEYCODE_NUM_KEYBOARD = -9; 67b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final int KEYCODE_ALPHA_KEYBOARD = -10; 68b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final int KEYCODE_CLOSE_KEYBOARD = -99; 69b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 70b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private Keyboard mQweKeyboard; 71b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private Keyboard mSymbolKeyboard; 72b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private Car mCar; 734db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi private CarUxRestrictionsManager mUxRManager; 74b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 75b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private View mLockoutView; 76b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private KeyboardView mPopupKeyboardView; 77b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 78b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @GuardedBy("this") 79b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private boolean mKeyboardEnabled = true; 80b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private KeyboardView mKeyboardView; 81b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private Locale mLocale; 82b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private final Handler mHandler; 83b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 84b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private FrameLayout mKeyboardWrapper; 85b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private EditorInfo mEditorInfo; 86b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 87b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private static final class HideKeyboardHandler extends Handler { 88b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private final WeakReference<CarLatinIME> mIME; 894db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi 90b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public HideKeyboardHandler(CarLatinIME ime) { 91b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mIME = new WeakReference<CarLatinIME>(ime); 92b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 934db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi 94b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 95b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void handleMessage(Message msg) { 96b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer switch (msg.what) { 97b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case MSG_ENABLE_KEYBOARD: 98b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mIME.get() != null) { 99b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mIME.get().updateKeyboardState(msg.arg1 == 1); 100b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 101b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 102b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 103b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 104b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 105b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 106b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private final ServiceConnection mCarConnectionListener = 107b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer new ServiceConnection() { 108b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onServiceConnected(ComponentName name, IBinder service) { 109b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Log.d(TAG, "Car Service connected"); 110b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer try { 1114db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi mUxRManager = (CarUxRestrictionsManager) mCar.getCarManager( 1124db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi Car.CAR_UX_RESTRICTION_SERVICE); 1134db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi if (mUxRManager != null) { 1144db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi mUxRManager.registerListener(mCarUxRListener); 1154db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi } else { 1164db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi Log.e(TAG, "CarUxRestrictions service not available"); 1174db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi } 118b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } catch (CarNotConnectedException e) { 119b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Log.e(TAG, "car not connected", e); 120b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 121b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 122b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 123b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 124b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onServiceDisconnected(ComponentName name) { 125b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Log.e(TAG, "CarService: onServiceDisconnedted " + name); 126b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 127b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer }; 128b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 1298c19f863a25c4549d7729baaeaef8dd656a96cf3Ram Periathiruvadi private final CarUxRestrictionsManager.OnUxRestrictionsChangedListener mCarUxRListener = 1308c19f863a25c4549d7729baaeaef8dd656a96cf3Ram Periathiruvadi new CarUxRestrictionsManager.OnUxRestrictionsChangedListener() { 131b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 1324db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi public void onUxRestrictionsChanged(CarUxRestrictions restrictions) { 1334db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi if (restrictions == null) { 134b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return; 135b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 136b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer boolean keyboardEnabled = 1374db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi (restrictions.getActiveRestrictions() 1384db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi & CarUxRestrictions.UX_RESTRICTIONS_NO_KEYBOARD) == 0; 139b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mHandler.sendMessage(mHandler.obtainMessage( 140b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer MSG_ENABLE_KEYBOARD, keyboardEnabled ? 1 : 0, 0, null)); 141b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 142b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer }; 143b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 144b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public CarLatinIME() { 145b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer super(); 146b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mHandler = new HideKeyboardHandler(this); 147b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 148b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 149b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 150b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onCreate() { 151b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer super.onCreate(); 152b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mCar = Car.createCar(this, mCarConnectionListener); 153b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mCar.connect(); 154b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 155b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mQweKeyboard = createKeyboard(LAYOUT_XML); 156b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mSymbolKeyboard = createKeyboard(SYMBOL_LAYOUT_XML); 157b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 158b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 159b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 160b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onDestroy() { 161b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer super.onDestroy(); 162b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mCar != null) { 163b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mCar.disconnect(); 164b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 165b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 166b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 167b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 168b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public View onCreateInputView() { 169b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (Log.isLoggable(TAG, Log.DEBUG)) { 170b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Log.d(TAG, "onCreateInputView"); 171b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 172b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer super.onCreateInputView(); 173b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 174b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer View v = LayoutInflater.from(this).inflate(R.layout.input_keyboard, null); 175b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView = (KeyboardView) v.findViewById(R.id.keyboard); 176b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 177b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mLockoutView = v.findViewById(R.id.lockout); 178b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mPopupKeyboardView = (KeyboardView) v.findViewById(R.id.popup_keyboard); 179b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setPopupKeyboardView(mPopupKeyboardView); 180b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardWrapper = (FrameLayout) v.findViewById(R.id.keyboard_wrapper); 181b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mLockoutView.setBackgroundResource(R.color.ime_background_letters); 182b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 183b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer synchronized (this) { 184b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer updateKeyboardStateLocked(); 185b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 186b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return v; 187b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 188b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 189b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 190b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 191b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onStartInputView(EditorInfo editorInfo, boolean reastarting) { 192b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer super.onStartInputView(editorInfo, reastarting); 193b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mEditorInfo = editorInfo; 194b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setKeyboard(mQweKeyboard, getLocale()); 195b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardWrapper.setPadding(0, 196b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer getResources().getDimensionPixelSize(R.dimen.keyboard_padding_vertical), 0, 0); 197b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setOnKeyboardActionListener(mKeyboardActionListener); 198b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mPopupKeyboardView.setOnKeyboardActionListener(mPopupKeyboardActionListener); 199b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setShifted(mKeyboardView.isShifted()); 200b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer updateCapitalization(); 201b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 202b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 203b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public Locale getLocale() { 204b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mLocale == null) { 205b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mLocale = this.getResources().getConfiguration().locale; 206b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 207b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return mLocale; 208b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 209b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 210b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 211b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public boolean onEvaluateFullscreenMode() { 212b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return false; 213b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 214b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 215b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private Keyboard createKeyboard(String layoutXml) { 216b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Resources res = this.getResources(); 217b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Configuration configuration = res.getConfiguration(); 218b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Locale oldLocale = configuration.locale; 219b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer configuration.locale = new Locale(DEFAULT_LANGUAGE); 220b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer res.updateConfiguration(configuration, res.getDisplayMetrics()); 221b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer Keyboard ret = new Keyboard( 222b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer this, res.getIdentifier(layoutXml, "xml", getPackageName())); 223b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mLocale = configuration.locale; 224b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer configuration.locale = oldLocale; 225b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return ret; 226b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 227b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 228b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void updateKeyboardState(boolean enabled) { 229b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer synchronized (this) { 230b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardEnabled = enabled; 231b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer updateKeyboardStateLocked(); 232b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 233b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 234b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 235b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private void updateKeyboardStateLocked() { 236b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mLockoutView == null) { 237b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return; 238b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 239b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mLockoutView.setVisibility(mKeyboardEnabled ? View.GONE : View.VISIBLE); 240b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 241b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 242b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private void toggleCapitalization() { 243b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setShifted(!mKeyboardView.isShifted()); 244b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 245b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 246b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private void updateCapitalization() { 247b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer boolean shouldCapitalize = 248b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer getCurrentInputConnection().getCursorCapsMode(mEditorInfo.inputType) != 0; 249b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setShifted(shouldCapitalize); 250b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 251b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 252b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private final KeyboardView.OnKeyboardActionListener mKeyboardActionListener = 253b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer new KeyboardView.OnKeyboardActionListener() { 254b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 255b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onPress(int primaryCode) { 256b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 257b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 258b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 259b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onRelease(int primaryCode) { 260b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 261b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 262b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 263b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onKey(int primaryCode, int[] keyCodes) { 264b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (Log.isLoggable(TAG, Log.DEBUG)) { 2654db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi Log.d(TAG, "onKey " + primaryCode); 266b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 267b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer InputConnection inputConnection = getCurrentInputConnection(); 268b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer switch (primaryCode) { 269b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case Keyboard.KEYCODE_SHIFT: 270b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer toggleCapitalization(); 271b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 272b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case Keyboard.KEYCODE_MODE_CHANGE: 273b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mKeyboardView.getKeyboard() == mQweKeyboard) { 274b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setKeyboard(mSymbolKeyboard, getLocale()); 275b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } else { 276b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setKeyboard(mQweKeyboard, getLocale()); 277b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 278b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 279b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case Keyboard.KEYCODE_DONE: 280b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer int action = mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION; 281b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer inputConnection.performEditorAction(action); 282b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 283b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case Keyboard.KEYCODE_DELETE: 284b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer inputConnection.deleteSurroundingText(1, 0); 285b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer updateCapitalization(); 286b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 287b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case KEYCODE_MAIN_KEYBOARD: 288b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.setKeyboard(mQweKeyboard, getLocale()); 289b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 290b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case KEYCODE_NUM_KEYBOARD: 291b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer // No number keyboard layout support. 292b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 293b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case KEYCODE_ALPHA_KEYBOARD: 294b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer //loadKeyboard(ALPHA_LAYOUT_XML); 295b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 296b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case KEYCODE_CLOSE_KEYBOARD: 297b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer hideWindow(); 298b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 299b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer case KEYCODE_CYCLE_CHAR: 300b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer CharSequence text = inputConnection.getTextBeforeCursor(1, 0); 301b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (TextUtils.isEmpty(text)) { 302b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 303b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 304b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 305b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer char currChar = text.charAt(0); 306b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer char altChar = cycleCharacter(currChar); 307b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer // Don't modify text if there is no alternate. 308b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (currChar != altChar) { 309b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer inputConnection.deleteSurroundingText(1, 0); 310b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer inputConnection.commitText(String.valueOf(altChar), 1); 311b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 312b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer break; 31360ee7843f916e9860d14a627734367ef6983566brleix case KEYCODE_ENTER: 3144db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi final int imeOptionsActionId = getImeOptionsActionIdFromEditorInfo( 3154db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi mEditorInfo); 31660ee7843f916e9860d14a627734367ef6983566brleix if (IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) { 3174db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // Either we have an actionLabel and we should 3184db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // performEditorAction with 31960ee7843f916e9860d14a627734367ef6983566brleix // actionId regardless of its value. 32060ee7843f916e9860d14a627734367ef6983566brleix inputConnection.performEditorAction(mEditorInfo.actionId); 32160ee7843f916e9860d14a627734367ef6983566brleix } else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) { 3224db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // We didn't have an actionLabel, but we had another action to 3234db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // execute. 3244db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // EditorInfo.IME_ACTION_NONE explicitly means no action. In 3254db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // contrast, 3264db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // EditorInfo.IME_ACTION_UNSPECIFIED is the default value for an 3274db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // action, so it 3284db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // means there should be an action and the app didn't bother to 3294db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // set a specific 3304db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // code for it - presumably it only handles one. It does not have 3314db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // to be treated 3324db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // in any specific way: anything that is not IME_ACTION_NONE 3334db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // should be sent to 33460ee7843f916e9860d14a627734367ef6983566brleix // performEditorAction. 33560ee7843f916e9860d14a627734367ef6983566brleix inputConnection.performEditorAction(imeOptionsActionId); 33660ee7843f916e9860d14a627734367ef6983566brleix } else { 3374db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // No action label, and the action from imeOptions is NONE: this 3384db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi // is a regular 33960ee7843f916e9860d14a627734367ef6983566brleix // enter key that should input a carriage return. 34060ee7843f916e9860d14a627734367ef6983566brleix String txt = Character.toString((char) primaryCode); 34160ee7843f916e9860d14a627734367ef6983566brleix if (mKeyboardView.isShifted()) { 34260ee7843f916e9860d14a627734367ef6983566brleix txt = txt.toUpperCase(mLocale); 34360ee7843f916e9860d14a627734367ef6983566brleix } 34460ee7843f916e9860d14a627734367ef6983566brleix if (Log.isLoggable(TAG, Log.DEBUG)) { 34560ee7843f916e9860d14a627734367ef6983566brleix Log.d(TAG, "commitText " + txt); 34660ee7843f916e9860d14a627734367ef6983566brleix } 34760ee7843f916e9860d14a627734367ef6983566brleix inputConnection.commitText(txt, 1); 34860ee7843f916e9860d14a627734367ef6983566brleix updateCapitalization(); 34960ee7843f916e9860d14a627734367ef6983566brleix } 35060ee7843f916e9860d14a627734367ef6983566brleix break; 351b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer default: 352b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer String commitText = Character.toString((char) primaryCode); 353b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer // Chars always come through as lowercase, so we have to explicitly 354b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer // uppercase them if the keyboard is shifted. 355b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mKeyboardView.isShifted()) { 356b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer commitText = commitText.toUpperCase(mLocale); 357b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 358b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (Log.isLoggable(TAG, Log.DEBUG)) { 3594db4661c51d6c6a260faf6fb44367676a4c6d4e5Ram Periathiruvadi Log.d(TAG, "commitText " + commitText); 360b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 361b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer inputConnection.commitText(commitText, 1); 362b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer updateCapitalization(); 363b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 364b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 365b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 366b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 367b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onText(CharSequence text) { 368b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 369b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 370b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 371b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeLeft() { 372b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 373b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 374b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 375b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeRight() { 376b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 377b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 378b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 379b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeDown() { 380b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 381b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 382b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 383b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeUp() { 384b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 385b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 386b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 387b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void stopInput() { 388b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer hideWindow(); 389b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 390b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer }; 391b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 392b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private final KeyboardView.OnKeyboardActionListener mPopupKeyboardActionListener = 393b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer new KeyboardView.OnKeyboardActionListener() { 394b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 395b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onPress(int primaryCode) { 396b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 397b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 398b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 399b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onRelease(int primaryCode) { 400b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 401b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 402b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 403b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onKey(int primaryCode, int[] keyCodes) { 404b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer InputConnection inputConnection = getCurrentInputConnection(); 405b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer String commitText = Character.toString((char) primaryCode); 406b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer // Chars always come through as lowercase, so we have to explicitly 407b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer // uppercase them if the keyboard is shifted. 408b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (mKeyboardView.isShifted()) { 409b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer commitText = commitText.toUpperCase(mLocale); 410b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 411b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer inputConnection.commitText(commitText, 1); 412b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer updateCapitalization(); 413b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer mKeyboardView.dismissPopupKeyboard(); 414b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 415b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 416b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 417b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void onText(CharSequence text) { 418b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 419b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 420b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 421b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeLeft() { 422b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 423b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 424b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 425b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeRight() { 426b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 427b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 428b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 429b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeDown() { 430b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 431b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 432b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 433b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void swipeUp() { 434b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 435b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 436b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer @Override 437b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer public void stopInput() { 438b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer hideWindow(); 439b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 440b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer }; 441b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer 442b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer /** 443b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * Cycle through alternate characters of the given character. Return the same character if 444b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer * there is no alternate. 445b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer */ 446b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer private char cycleCharacter(char current) { 447b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer if (Character.isUpperCase(current)) { 448b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return String.valueOf(current).toLowerCase(mLocale).charAt(0); 449b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } else { 450b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer return String.valueOf(current).toUpperCase(mLocale).charAt(0); 451b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 452b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer } 45360ee7843f916e9860d14a627734367ef6983566brleix 45460ee7843f916e9860d14a627734367ef6983566brleix private int getImeOptionsActionIdFromEditorInfo(final EditorInfo editorInfo) { 45560ee7843f916e9860d14a627734367ef6983566brleix if ((editorInfo.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) { 45660ee7843f916e9860d14a627734367ef6983566brleix return EditorInfo.IME_ACTION_NONE; 45760ee7843f916e9860d14a627734367ef6983566brleix } else if (editorInfo.actionLabel != null) { 45860ee7843f916e9860d14a627734367ef6983566brleix return IME_ACTION_CUSTOM_LABEL; 45960ee7843f916e9860d14a627734367ef6983566brleix } else { 46060ee7843f916e9860d14a627734367ef6983566brleix // Note: this is different from editorInfo.actionId, hence "ImeOptionsActionId" 46160ee7843f916e9860d14a627734367ef6983566brleix return editorInfo.imeOptions & EditorInfo.IME_MASK_ACTION; 46260ee7843f916e9860d14a627734367ef6983566brleix } 46360ee7843f916e9860d14a627734367ef6983566brleix } 464b8d05222f6f88e9c6ab64f88e9b9eba194a5c221Rakesh Iyer} 465