diff options
Diffstat (limited to 'java/src')
7 files changed, 130 insertions, 164 deletions
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index a013ebca9..f632b0e02 100644 --- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java +++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java @@ -16,23 +16,6 @@ package com.android.inputmethod.deprecated; -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; -import com.android.inputmethod.compat.SharedPreferencesCompat; -import com.android.inputmethod.deprecated.voice.FieldContext; -import com.android.inputmethod.deprecated.voice.Hints; -import com.android.inputmethod.deprecated.voice.SettingsUtil; -import com.android.inputmethod.deprecated.voice.VoiceInput; -import com.android.inputmethod.keyboard.KeyboardSwitcher; -import com.android.inputmethod.latin.EditingUtils; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.LatinIME.UIHandler; -import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeSwitcher; -import com.android.inputmethod.latin.SuggestedWords; -import com.android.inputmethod.latin.Utils; - import android.app.AlertDialog; import android.content.ContentResolver; import android.content.Context; @@ -63,6 +46,24 @@ import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.widget.TextView; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; +import com.android.inputmethod.compat.SharedPreferencesCompat; +import com.android.inputmethod.deprecated.voice.FieldContext; +import com.android.inputmethod.deprecated.voice.Hints; +import com.android.inputmethod.deprecated.voice.SettingsUtil; +import com.android.inputmethod.deprecated.voice.VoiceInput; +import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.keyboard.LatinKeyboardView; +import com.android.inputmethod.latin.EditingUtils; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.LatinIME.UIHandler; +import com.android.inputmethod.latin.LatinImeLogger; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.SuggestedWords; +import com.android.inputmethod.latin.Utils; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -747,8 +748,9 @@ public class VoiceProxy implements VoiceInput.UiListener { // keep showing the warning. if (mSubtypeSwitcher.isVoiceMode() && windowToken != null) { // Close keyboard view if it is been shown. - if (KeyboardSwitcher.getInstance().isInputViewShown()) - KeyboardSwitcher.getInstance().getKeyboardView().purgeKeyboardAndClosing(); + final LatinKeyboardView keyboardView = KeyboardSwitcher.getInstance().getKeyboardView(); + if (keyboardView != null && keyboardView.isShown()) + keyboardView.purgeKeyboardAndClosing(); startListening(false, windowToken); } // If we have no token, onAttachedToWindow will take care of showing dialog and start diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index 0aed5068c..d35948bad 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -59,6 +59,14 @@ public class KeyboardSet { private final Params mParams; private final KeysCache mKeysCache = new KeysCache(); + public static class KeyboardSetException extends RuntimeException { + public final KeyboardId mKeyboardId; + public KeyboardSetException(Throwable cause, KeyboardId keyboardId) { + super(cause); + mKeyboardId = keyboardId; + } + } + public static class KeysCache { private final Map<Key, Key> mMap; @@ -107,11 +115,6 @@ public class KeyboardSet { mParams = params; } - // TODO: Remove this method, use {@link #getKeyboard} directly. - public Keyboard getMainKeyboard() { - return getKeyboard(KeyboardId.ELEMENT_ALPHABET); - } - public Keyboard getKeyboard(int baseKeyboardSetElementId) { final int keyboardSetElementId; switch (mParams.mMode) { @@ -134,8 +137,11 @@ public class KeyboardSet { KeyboardId.ELEMENT_ALPHABET); } final KeyboardId id = getKeyboardId(keyboardSetElementId); - final Keyboard keyboard = getKeyboard(mContext, keyboardXmlId, id); - return keyboard; + try { + return getKeyboard(mContext, keyboardXmlId, id); + } catch (RuntimeException e) { + throw new KeyboardSetException(e, id); + } } private Keyboard getKeyboard(Context context, int keyboardXmlId, KeyboardId id) { @@ -169,11 +175,10 @@ public class KeyboardSet { return keyboard; } - // TODO: Make this method private. // Note: The keyboard for each locale, shift state, and mode are represented as KeyboardSet // element id that is a key in keyboard_set.xml. Also that file specifies which XML layout // should be used for each keyboard. The KeyboardId is an internal key for Keyboard object. - public KeyboardId getKeyboardId(int keyboardSetElementId) { + private KeyboardId getKeyboardId(int keyboardSetElementId) { final Params params = mParams; final boolean isSymbols = (keyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS || keyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 17ad45df0..951bcdbfd 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -27,6 +27,8 @@ import android.view.View; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; +import com.android.inputmethod.keyboard.KeyboardSet.KeyboardSetException; +import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.internal.KeyboardState; import com.android.inputmethod.latin.DebugSettings; import com.android.inputmethod.latin.InputView; @@ -137,11 +139,9 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, mKeyboardSet = builder.build(); try { mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); - } catch (RuntimeException e) { - Log.w(TAG, "loading keyboard failed: " + mKeyboardSet.getKeyboardId( - KeyboardId.ELEMENT_ALPHABET), e); - LatinImeLogger.logOnException(mKeyboardSet.getKeyboardId( - KeyboardId.ELEMENT_ALPHABET).toString(), e); + } catch (KeyboardSetException e) { + Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause()); + LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause()); return; } } @@ -179,23 +179,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged); } - // TODO: Remove this method. - public boolean isAlphabetMode() { - final Keyboard keyboard = getKeyboard(); - return keyboard != null && keyboard.mId.isAlphabetKeyboard(); - } - - // TODO: Remove this method. - public boolean isInputViewShown() { - return mCurrentInputView != null && mCurrentInputView.isShown(); - } - - // TODO: Remove this method. - public boolean isShiftedOrShiftLocked() { - final Keyboard keyboard = getKeyboard(); - return keyboard != null && keyboard.isShiftedOrShiftLocked(); - } - public Keyboard getKeyboard() { if (mKeyboardView != null) { return mKeyboardView.getKeyboard(); @@ -270,6 +253,24 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState()); } + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void startDoubleTapTimer() { + final LatinKeyboardView keyboardView = getKeyboardView(); + if (keyboardView != null) { + final TimerProxy timer = keyboardView.getTimerProxy(); + timer.startDoubleTapTimer(); + } + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public boolean isInDoubleTapTimeout() { + final LatinKeyboardView keyboardView = getKeyboardView(); + return (keyboardView != null) + ? keyboardView.getTimerProxy().isInDoubleTapTimeout() : false; + } + public boolean isInMomentarySwitchState() { return mState.isInMomentarySwitchState(); } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 056aa255d..5aad67d49 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -29,7 +29,6 @@ import android.os.Message; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; -import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -64,8 +63,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke SuddenJumpingTouchEventHandler.ProcessMotionEvent { private static final String TAG = LatinKeyboardView.class.getSimpleName(); - private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true; - // TODO: Kill process when the usability study mode was changed. private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy; @@ -111,16 +108,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private int mOldPointerCount = 1; private Key mOldKey; - // To detect double tap. - protected GestureDetector mGestureDetector; - private final KeyTimerHandler mKeyTimerHandler; private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView> implements TimerProxy { private static final int MSG_REPEAT_KEY = 1; private static final int MSG_LONGPRESS_KEY = 2; - private static final int MSG_IGNORE_DOUBLE_TAP = 3; + private static final int MSG_DOUBLE_TAP = 3; private static final int MSG_KEY_TYPED = 4; private final int mKeyRepeatInterval; @@ -184,70 +178,24 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } @Override - public void cancelKeyTimers() { - cancelKeyRepeatTimer(); - cancelLongPressTimer(); - removeMessages(MSG_IGNORE_DOUBLE_TAP); - } - - public void startIgnoringDoubleTap() { - sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP), + public void startDoubleTapTimer() { + sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP), ViewConfiguration.getDoubleTapTimeout()); } - public boolean isIgnoringDoubleTap() { - return hasMessages(MSG_IGNORE_DOUBLE_TAP); - } - - public void cancelAllMessages() { - cancelKeyTimers(); + @Override + public boolean isInDoubleTapTimeout() { + return hasMessages(MSG_DOUBLE_TAP); } - } - - class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { - private boolean mProcessingShiftDoubleTapEvent = false; @Override - public boolean onDoubleTap(MotionEvent firstDown) { - final Keyboard keyboard = getKeyboard(); - if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard.mId.isAlphabetKeyboard()) { - final int pointerIndex = firstDown.getActionIndex(); - final int id = firstDown.getPointerId(pointerIndex); - final PointerTracker tracker = PointerTracker.getPointerTracker( - id, LatinKeyboardView.this); - final Key key = tracker.getKeyOn((int)firstDown.getX(), (int)firstDown.getY()); - // If the first down event is on shift key. - if (key != null && key.isShift()) { - mProcessingShiftDoubleTapEvent = true; - return true; - } - } - mProcessingShiftDoubleTapEvent = false; - return false; + public void cancelKeyTimers() { + cancelKeyRepeatTimer(); + cancelLongPressTimer(); } - @Override - public boolean onDoubleTapEvent(MotionEvent secondTap) { - if (mProcessingShiftDoubleTapEvent - && secondTap.getAction() == MotionEvent.ACTION_DOWN) { - final MotionEvent secondDown = secondTap; - final int pointerIndex = secondDown.getActionIndex(); - final int id = secondDown.getPointerId(pointerIndex); - final PointerTracker tracker = PointerTracker.getPointerTracker( - id, LatinKeyboardView.this); - final Key key = tracker.getKeyOn((int)secondDown.getX(), (int)secondDown.getY()); - // If the second down event is also on shift key. - if (key != null && key.isShift()) { - // Detected a double tap on shift key. If we are in the ignoring double tap - // mode, it means we have already turned off caps lock in - // {@link KeyboardSwitcher#onReleaseShift} . - onDoubleTapShiftKey(mKeyTimerHandler.isIgnoringDoubleTap()); - return true; - } - // Otherwise these events should not be handled as double tap. - mProcessingShiftDoubleTapEvent = false; - } - return mProcessingShiftDoubleTapEvent; + public void cancelAllMessages() { + cancelKeyTimers(); } } @@ -303,11 +251,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this); - final boolean ignoreMultitouch = true; - mGestureDetector = new GestureDetector( - getContext(), new DoubleTapListener(), null, ignoreMultitouch); - mGestureDetector.setIsLongpressEnabled(false); - mHasDistinctMultitouch = context.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT); @@ -342,11 +285,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke PointerTracker.setParameters(mPointerTrackerParams); } - public void startIgnoringDoubleTap() { - if (ENABLE_CAPSLOCK_BY_DOUBLETAP) - mKeyTimerHandler.startIgnoringDoubleTap(); - } - public void setKeyboardActionListener(KeyboardActionListener listener) { mKeyboardActionListener = listener; PointerTracker.setKeyboardActionListener(listener); @@ -451,17 +389,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke return onLongPress(parentKey, tracker); } - private void onDoubleTapShiftKey(final boolean ignore) { - // When shift key is double tapped, the first tap is correctly processed as usual tap. And - // the second tap is treated as this double tap event, so that we need not mark tracker - // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue. - if (ignore) { - invokeCustomRequest(LatinIME.CODE_HAPTIC_AND_AUDIO_FEEDBACK); - } else { - invokeCodeInput(Keyboard.CODE_CAPSLOCK); - } - } - // This default implementation returns a more keys panel. protected MoreKeysPanel onCreateMoreKeysPanel(Key parentKey) { if (parentKey.mMoreKeys == null) @@ -595,14 +522,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke return true; } - // Gesture detector must be enabled only when mini-keyboard is not on the screen. - if (mMoreKeysPanel == null && mGestureDetector != null - && mGestureDetector.onTouchEvent(me)) { - PointerTracker.dismissAllKeyPreviews(); - mKeyTimerHandler.cancelKeyTimers(); - return true; - } - final long eventTime = me.getEventTime(); final int index = me.getActionIndex(); final int id = me.getPointerId(index); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 4dac3474d..fc92a24a6 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -76,6 +76,8 @@ public class PointerTracker { public void startKeyRepeatTimer(long delay, PointerTracker tracker); public void startLongPressTimer(long delay, PointerTracker tracker); public void cancelLongPressTimer(); + public void startDoubleTapTimer(); + public boolean isInDoubleTapTimeout(); public void cancelKeyTimers(); public static class Adapter implements TimerProxy { @@ -90,6 +92,10 @@ public class PointerTracker { @Override public void cancelLongPressTimer() {} @Override + public void startDoubleTapTimer() {} + @Override + public boolean isInDoubleTapTimeout() { return false; } + @Override public void cancelKeyTimers() {} } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java index 38837f519..1de83866f 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java @@ -51,6 +51,9 @@ public class KeyboardState { * Request to call back {@link KeyboardState#onUpdateShiftState(boolean)}. */ public void requestUpdatingShiftState(); + + public void startDoubleTapTimer(); + public boolean isInDoubleTapTimeout(); } private final SwitchActions mSwitchActions; @@ -75,6 +78,10 @@ public class KeyboardState { private boolean mPrevMainKeyboardWasShiftLocked; private boolean mPrevSymbolsKeyboardWasShifted; + // For handling double tap. + private boolean mIsInAlphabetUnshiftedFromShifted; + private boolean mIsInDoubleTapShiftKey; + private final SavedKeyboardState mSavedKeyboardState = new SavedKeyboardState(); static class SavedKeyboardState { @@ -258,8 +265,7 @@ public class KeyboardState { mSwitchActions.requestUpdatingShiftState(); } - // TODO: Make this method private - public void setSymbolsKeyboard() { + private void setSymbolsKeyboard() { if (DEBUG_ACTION) { Log.d(TAG, "setSymbolsKeyboard"); } @@ -350,22 +356,35 @@ public class KeyboardState { private void onPressShift() { if (mIsAlphabetMode) { - if (mAlphabetShiftState.isShiftLocked()) { - // Shift key is pressed while caps lock state, we will treat this state as shifted - // caps lock state and mark as if shift key pressed while normal state. + mIsInDoubleTapShiftKey = mSwitchActions.isInDoubleTapTimeout(); + if (!mIsInDoubleTapShiftKey) { + // This is first tap. + mSwitchActions.startDoubleTapTimer(); + } + if (mIsInDoubleTapShiftKey) { + if (mAlphabetShiftState.isManualShifted() || mIsInAlphabetUnshiftedFromShifted) { + // Shift key has been double tapped while in manual shifted or automatic + // shifted state. + setShiftLocked(true); + } else { + // Shift key has been double tapped while in normal state. This is the second + // tap to disable shift locked state, so just ignore this. + } + } else if (mAlphabetShiftState.isShiftLocked()) { + // Shift key is pressed while shift locked state, we will treat this state as + // shift lock shifted state and mark as if shift key pressed while normal state. setShifted(SHIFT_LOCK_SHIFTED); mShiftKeyState.onPress(); } else if (mAlphabetShiftState.isAutomaticShifted()) { - // Shift key is pressed while automatic temporary upper case, we have to move to - // manual temporary upper case. + // Shift key is pressed while automatic shifted, we have to move to manual shifted. setShifted(MANUAL_SHIFT); mShiftKeyState.onPress(); } else if (mAlphabetShiftState.isShiftedOrShiftLocked()) { - // In manual upper case state, we just record shift key has been pressing while + // In manual shifted state, we just record shift key has been pressing while // shifted state. mShiftKeyState.onPressOnShifted(); } else { - // In base layout, chording or manual temporary upper case mode is started. + // In base layout, chording or manual shifted mode is started. setShifted(MANUAL_SHIFT); mShiftKeyState.onPress(); } @@ -380,33 +399,40 @@ public class KeyboardState { private void onReleaseShift(boolean withSliding) { if (mIsAlphabetMode) { final boolean isShiftLocked = mAlphabetShiftState.isShiftLocked(); - if (mShiftKeyState.isChording()) { + mIsInAlphabetUnshiftedFromShifted = false; + if (mIsInDoubleTapShiftKey) { + // Double tap shift key has been handled in {@link #onPressShift}, so that just + // ignore this release shift key here. + mIsInDoubleTapShiftKey = false; + } else if (mShiftKeyState.isChording()) { if (mAlphabetShiftState.isShiftLockShifted()) { - // After chording input while caps lock state. + // After chording input while shift locked state. setShiftLocked(true); } else { // After chording input while normal state. setShifted(UNSHIFT); } } else if (mAlphabetShiftState.isShiftLockShifted() && withSliding) { - // In caps lock state, shift has been pressed and slid out to other key. + // In shift locked state, shift has been pressed and slid out to other key. setShiftLocked(true); } else if (isShiftLocked && !mAlphabetShiftState.isShiftLockShifted() && (mShiftKeyState.isPressing() || mShiftKeyState.isPressingOnShifted()) && !withSliding) { // Shift has been long pressed, ignore this release. } else if (isShiftLocked && !mShiftKeyState.isIgnoring() && !withSliding) { - // Shift has been pressed without chording while caps lock state. + // Shift has been pressed without chording while shift locked state. setShiftLocked(false); } else if (mAlphabetShiftState.isShiftedOrShiftLocked() && mShiftKeyState.isPressingOnShifted() && !withSliding) { // Shift has been pressed without chording while shifted state. setShifted(UNSHIFT); + mIsInAlphabetUnshiftedFromShifted = true; } else if (mAlphabetShiftState.isManualShiftedFromAutomaticShifted() && mShiftKeyState.isPressing() && !withSliding) { - // Shift has been pressed without chording while manual temporary upper case - // transited from automatic temporary upper case. + // Shift has been pressed without chording while manual shifted transited from + // automatic shifted setShifted(UNSHIFT); + mIsInAlphabetUnshiftedFromShifted = true; } } else { // In symbol mode, switch back to the previous keyboard mode if the user chords the @@ -457,10 +483,11 @@ public class KeyboardState { if (mIsAlphabetMode && code == Keyboard.CODE_CAPSLOCK) { if (mAlphabetShiftState.isShiftLocked()) { setShiftLocked(false); - // Shift key is long pressed or double tapped while caps lock state, we will - // toggle back to normal state. And mark as if shift key is released. + // Shift key is long pressed while shift locked state, we will toggle back to normal + // state. And mark as if shift key is released. mShiftKeyState.onRelease(); } else { + // Shift key is long pressed while shift unloked state. setShiftLocked(true); } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 0d6395d97..1e7171406 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -291,8 +291,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar latinIme.updateBigramPredictions(); break; case MSG_VOICE_RESULTS: + final Keyboard keyboard = switcher.getKeyboard(); latinIme.mVoiceProxy.handleVoiceResults(latinIme.preferCapitalization() - || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); + || (keyboard != null && keyboard.isShiftedOrShiftLocked())); break; case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: setSpacebarTextFadeFactor(inputView, @@ -987,8 +988,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private void setSuggestionStripShownInternal(boolean shown, boolean needsInputViewShown) { // TODO: Modify this if we support suggestions with hard keyboard if (onEvaluateInputViewShown() && mSuggestionsContainer != null) { + final LatinKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView(); + final boolean inputViewShown = (keyboardView != null) ? keyboardView.isShown() : false; final boolean shouldShowSuggestions = shown - && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); + && (needsInputViewShown ? inputViewShown : true); if (isFullscreenMode()) { mSuggestionsContainer.setVisibility( shouldShowSuggestions ? View.VISIBLE : View.GONE); @@ -1020,7 +1023,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final int extraHeight = extractHeight + backingHeight + suggestionsHeight; int touchY = extraHeight; // Need to set touchable region only if input view is being shown - if (mKeyboardSwitcher.isInputViewShown()) { + final LatinKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView(); + if (keyboardView != null && keyboardView.isShown()) { if (mSuggestionsContainer.getVisibility() == View.VISIBLE) { touchY -= suggestionsHeight; } @@ -1081,9 +1085,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar case KeyEvent.KEYCODE_DPAD_UP: case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_RIGHT: + final LatinKeyboardView keyboardView = mKeyboardSwitcher.getKeyboardView(); + final Keyboard keyboard = mKeyboardSwitcher.getKeyboard(); // Enable shift key and DPAD to do selections - if (mKeyboardSwitcher.isInputViewShown() - && mKeyboardSwitcher.isShiftedOrShiftLocked()) { + if ((keyboardView != null && keyboardView.isShown()) + && (keyboard != null && keyboard.isShiftedOrShiftLocked())) { KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(), event.getAction(), event.getKeyCode(), event.getRepeatCount(), event.getDeviceId(), event.getScanCode(), |