Ignore the Emoji key when not connected.

When the LatinIME does not have an active InputConnection, it will not try
to toggle the Emoji keyboard.

Bug 19513415.

Change-Id: I31f928cd7db1cddd771c548cd3dc42f8af64d0e2
This commit is contained in:
Dan Zivkovic 2015-02-26 11:10:37 -08:00
parent 48b071249c
commit edd94a449e
3 changed files with 49 additions and 27 deletions

View file

@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
import android.util.Log;
import android.view.KeyEvent;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
@ -25,10 +26,18 @@ import com.android.inputmethod.latin.settings.Settings;
* A class for detecting Emoji-Alt physical key.
*/
final class EmojiAltPhysicalKeyDetector {
private static final String TAG = "EmojiAltPhysicalKeyDetector";
private final RichInputConnection mRichInputConnection;
// True if the Alt key has been used as a modifier. In this case the Alt key up isn't
// recognized as an emoji key.
private boolean mAltHasBeenUsedAsAModifier;
public EmojiAltPhysicalKeyDetector(final RichInputConnection richInputConnection) {
mRichInputConnection = richInputConnection;
}
/**
* Record a down key event.
* @param keyEvent a down key event.
@ -62,9 +71,14 @@ final class EmojiAltPhysicalKeyDetector {
if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
return;
}
if (!mAltHasBeenUsedAsAModifier) {
onEmojiAltKeyDetected();
if (mAltHasBeenUsedAsAModifier) {
return;
}
if (!mRichInputConnection.isConnected()) {
Log.w(TAG, "onKeyUp() : No connection to text view");
return;
}
onEmojiAltKeyDetected();
}
private static void onEmojiAltKeyDetected() {

View file

@ -143,7 +143,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState();
private final EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector =
new EmojiAltPhysicalKeyDetector();
new EmojiAltPhysicalKeyDetector(mInputLogic.mConnection);
private StatsUtilsManager mStatsUtilsManager;
// Working variable for {@link #startShowingInputView()} and
// {@link #onEvaluateInputViewShown()}.

View file

@ -101,12 +101,17 @@ public final class RichInputConnection implements PrivateCommandPerformer {
private final InputMethodService mParent;
InputConnection mIC;
int mNestLevel;
public RichInputConnection(final InputMethodService parent) {
mParent = parent;
mIC = null;
mNestLevel = 0;
}
public boolean isConnected() {
return mIC != null;
}
private void checkConsistencyForDebug() {
final ExtractedTextRequest r = new ExtractedTextRequest();
r.hintMaxChars = 0;
@ -142,7 +147,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public void beginBatchEdit() {
if (++mNestLevel == 1) {
mIC = mParent.getCurrentInputConnection();
if (null != mIC) {
if (isConnected()) {
mIC.beginBatchEdit();
}
} else {
@ -157,7 +162,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public void endBatchEdit() {
if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
if (--mNestLevel == 0 && null != mIC) {
if (--mNestLevel == 0 && isConnected()) {
mIC.endBatchEdit();
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
@ -189,7 +194,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
Log.d(TAG, "Will try to retrieve text later.");
return false;
}
if (null != mIC && shouldFinishComposition) {
if (isConnected() && shouldFinishComposition) {
mIC.finishComposingText();
}
return true;
@ -205,8 +210,9 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mIC = mParent.getCurrentInputConnection();
// Call upon the inputconnection directly since our own method is using the cache, and
// we want to refresh it.
final CharSequence textBeforeCursor = null == mIC ? null :
mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
final CharSequence textBeforeCursor = isConnected()
? mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE, 0)
: null;
if (null == textBeforeCursor) {
// For some reason the app thinks we are not connected to it. This looks like a
// framework bug... Fall back to ground state and return false.
@ -235,7 +241,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
// it works, but it's wrong and should be fixed.
mCommittedTextBeforeComposingText.append(mComposingText);
mComposingText.setLength(0);
if (null != mIC) {
if (isConnected()) {
mIC.finishComposingText();
}
}
@ -256,7 +262,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mExpectedSelStart += text.length() - mComposingText.length();
mExpectedSelEnd = mExpectedSelStart;
mComposingText.setLength(0);
if (null != mIC) {
if (isConnected()) {
mTempObjectForCommitText.clear();
mTempObjectForCommitText.append(text);
final CharacterStyle[] spans = mTempObjectForCommitText.getSpans(
@ -283,7 +289,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
}
public CharSequence getSelectedText(final int flags) {
return (null == mIC) ? null : mIC.getSelectedText(flags);
return isConnected() ? mIC.getSelectedText(flags) : null;
}
public boolean canDeleteCharacters() {
@ -308,7 +314,9 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public int getCursorCapsMode(final int inputType,
final SpacingAndPunctuations spacingAndPunctuations, final boolean hasSpaceBefore) {
mIC = mParent.getCurrentInputConnection();
if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF;
if (!isConnected()) {
return Constants.TextUtils.CAP_MODE_OFF;
}
if (!TextUtils.isEmpty(mComposingText)) {
if (hasSpaceBefore) {
// If we have some composing text and a space before, then we should have
@ -368,12 +376,12 @@ public final class RichInputConnection implements PrivateCommandPerformer {
return s;
}
mIC = mParent.getCurrentInputConnection();
return (null == mIC) ? null : mIC.getTextBeforeCursor(n, flags);
return isConnected() ? mIC.getTextBeforeCursor(n, flags) : null;
}
public CharSequence getTextAfterCursor(final int n, final int flags) {
mIC = mParent.getCurrentInputConnection();
return (null == mIC) ? null : mIC.getTextAfterCursor(n, flags);
return isConnected() ? mIC.getTextAfterCursor(n, flags) : null;
}
public void deleteSurroundingText(final int beforeLength, final int afterLength) {
@ -400,7 +408,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mExpectedSelEnd -= mExpectedSelStart;
mExpectedSelStart = 0;
}
if (null != mIC) {
if (isConnected()) {
mIC.deleteSurroundingText(beforeLength, afterLength);
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
@ -408,7 +416,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public void performEditorAction(final int actionId) {
mIC = mParent.getCurrentInputConnection();
if (null != mIC) {
if (isConnected()) {
mIC.performEditorAction(actionId);
}
}
@ -460,7 +468,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
break;
}
}
if (null != mIC) {
if (isConnected()) {
mIC.sendKeyEvent(keyEvent);
}
}
@ -483,7 +491,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mCommittedTextBeforeComposingText.append(
textBeforeCursor.subSequence(0, indexOfStartOfComposingText));
}
if (null != mIC) {
if (isConnected()) {
mIC.setComposingRegion(start, end);
}
}
@ -497,7 +505,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mComposingText.append(text);
// TODO: support values of newCursorPosition != 1. At this time, this is never called with
// newCursorPosition != 1.
if (null != mIC) {
if (isConnected()) {
mIC.setComposingText(text, newCursorPosition);
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
@ -522,7 +530,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
}
mExpectedSelStart = start;
mExpectedSelEnd = end;
if (null != mIC) {
if (isConnected()) {
final boolean isIcValid = mIC.setSelection(start, end);
if (!isIcValid) {
return false;
@ -536,7 +544,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
// This has no effect on the text field and does not change its content. It only makes
// TextView flash the text for a second based on indices contained in the argument.
if (null != mIC) {
if (isConnected()) {
mIC.commitCorrection(correctionInfo);
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
@ -552,7 +560,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mExpectedSelStart += text.length() - mComposingText.length();
mExpectedSelEnd = mExpectedSelStart;
mComposingText.setLength(0);
if (null != mIC) {
if (isConnected()) {
mIC.commitCompletion(completionInfo);
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
@ -563,7 +571,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public NgramContext getNgramContextFromNthPreviousWord(
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
mIC = mParent.getCurrentInputConnection();
if (null == mIC) {
if (!isConnected()) {
return NgramContext.EMPTY_PREV_WORDS_INFO;
}
final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
@ -608,7 +616,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public TextRange getWordRangeAtCursor(final SpacingAndPunctuations spacingAndPunctuations,
final int scriptId) {
mIC = mParent.getCurrentInputConnection();
if (mIC == null) {
if (!isConnected()) {
return null;
}
final CharSequence before = mIC.getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE,
@ -824,7 +832,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mIC = mParent.getCurrentInputConnection();
final CharSequence textBeforeCursor = getTextBeforeCursor(
Constants.EDITOR_CONTENTS_CACHE_SIZE, 0);
final CharSequence selectedText = null == mIC ? null : mIC.getSelectedText(0 /* flags */);
final CharSequence selectedText = isConnected() ? mIC.getSelectedText(0 /* flags */) : null;
if (null == textBeforeCursor ||
(!TextUtils.isEmpty(selectedText) && mExpectedSelEnd == mExpectedSelStart)) {
// If textBeforeCursor is null, we have no idea what kind of text field we have or if
@ -863,7 +871,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
@Override
public boolean performPrivateCommand(final String action, final Bundle data) {
mIC = mParent.getCurrentInputConnection();
if (mIC == null) {
if (!isConnected()) {
return false;
}
return mIC.performPrivateCommand(action, data);
@ -923,7 +931,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
public boolean requestCursorUpdates(final boolean enableMonitor,
final boolean requestImmediateCallback) {
mIC = mParent.getCurrentInputConnection();
if (mIC == null) {
if (!isConnected()) {
return false;
}
return InputConnectionCompatUtils.requestCursorUpdates(