From f87e8f7ec1efb93398d909c67468d716b0248fe7 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 2 Jul 2013 18:07:35 +0900 Subject: Handling key repeat by emulating key press and code input This change also eliminates a reference of AudioAndHapticFeedbackManager from KeyboardSwitcher and MainKeyboard. Bug: 6522943 Change-Id: Iac42ec8ff00c66deb76a660ffc07477923a58959 --- .../keyboard/KeyboardActionListener.java | 5 +-- .../inputmethod/keyboard/KeyboardSwitcher.java | 9 ----- .../inputmethod/keyboard/MainKeyboardView.java | 45 +++++++++------------- .../inputmethod/keyboard/PointerTracker.java | 9 +---- .../keyboard/internal/KeyboardState.java | 17 ++------ .../com/android/inputmethod/latin/Constants.java | 7 ++++ .../com/android/inputmethod/latin/LatinIME.java | 20 ++++++---- .../inputmethod/latin/RichInputConnection.java | 4 ++ 8 files changed, 50 insertions(+), 66 deletions(-) (limited to 'java/src') diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java index 9eeee5baf..00ea20d2c 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java @@ -20,7 +20,6 @@ import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.InputPointers; public interface KeyboardActionListener { - /** * Called when the user presses a key. This is sent before the {@link #onCodeInput} is called. * For keys that repeat, this is only called once. @@ -99,9 +98,9 @@ public interface KeyboardActionListener { */ public boolean onCustomRequest(int requestCode); - public static class Adapter implements KeyboardActionListener { - public static final Adapter EMPTY_LISTENER = new Adapter(); + public static final KeyboardActionListener EMPTY_LISTENER = new Adapter(); + public static class Adapter implements KeyboardActionListener { @Override public void onPressKey(int primaryCode, boolean isSinglePointer) {} @Override diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 4323f7171..98e2baee2 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -31,7 +31,6 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException; import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; import com.android.inputmethod.keyboard.internal.KeyboardState; -import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.InputView; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; @@ -210,7 +209,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { } public void onPressKey(final int code, final boolean isSinglePointer) { - hapticAndAudioFeedback(code); mState.onPressKey(code, isSinglePointer, mLatinIME.getCurrentAutoCapsState()); } @@ -299,13 +297,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { ? keyboardView.getTimerProxy().isInDoubleTapShiftKeyTimeout() : false; } - private void hapticAndAudioFeedback(final int code) { - if (mKeyboardView == null || mKeyboardView.isInSlidingKeyInput()) { - return; - } - AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(code, mKeyboardView); - } - /** * Updates state machine to figure out when to automatically switch back to the previous mode. */ diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 8a926d655..a4606f2f3 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -57,10 +57,8 @@ import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams; import com.android.inputmethod.keyboard.internal.PreviewPlacerView; import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview; import com.android.inputmethod.keyboard.internal.TouchScreenRegulator; -import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.DebugSettings; -import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.Settings; @@ -240,11 +238,15 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack break; case MSG_REPEAT_KEY: final Key currentKey = tracker.getKey(); - if (currentKey != null && currentKey.mCode == msg.arg1) { - tracker.onRepeatKey(currentKey); - AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback( - currentKey.mCode, keyboardView); + final int code = msg.arg1; + if (currentKey != null && currentKey.mCode == code) { startKeyRepeatTimer(tracker, mKeyRepeatInterval); + startTypingStateTimer(currentKey); + final KeyboardActionListener listener = + keyboardView.getKeyboardActionListener(); + listener.onPressKey(code, true /* isSinglePointer */); + listener.onCodeInput(code, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); } break; case MSG_LONGPRESS_KEY: @@ -564,6 +566,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack altCodeKeyWhileTypingFadeoutAnimatorResId, this); mAltCodeKeyWhileTypingFadeinAnimator = loadObjectAnimator( altCodeKeyWhileTypingFadeinAnimatorResId, this); + + mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER; } private ObjectAnimator loadObjectAnimator(final int resId, final Object target) { @@ -977,39 +981,28 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.mainKeyboardView_onLongPress(); } - final int code = key.mCode; + final KeyboardActionListener listener = mKeyboardActionListener; if (key.hasNoPanelAutoMoreKey()) { - final int embeddedCode = key.mMoreKeys[0].mCode; + final int moreKeyCode = key.mMoreKeys[0].mCode; tracker.onLongPressed(); - invokeCodeInput(embeddedCode); - invokeReleaseKey(code); - AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(code, this); + listener.onPressKey(moreKeyCode, true /* isSinglePointer */); + listener.onCodeInput(moreKeyCode, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); + listener.onReleaseKey(moreKeyCode, false /* withSliding */); return; } + final int code = key.mCode; if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) { // Long pressing the space key invokes IME switcher dialog. - if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) { + if (listener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) { tracker.onLongPressed(); - invokeReleaseKey(code); + listener.onReleaseKey(code, false /* withSliding */); return; } } openMoreKeysPanel(key, tracker); } - private boolean invokeCustomRequest(final int requestCode) { - return mKeyboardActionListener.onCustomRequest(requestCode); - } - - private void invokeCodeInput(final int code) { - mKeyboardActionListener.onCodeInput( - code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); - } - - private void invokeReleaseKey(final int code) { - mKeyboardActionListener.onReleaseKey(code, false); - } - private void openMoreKeysPanel(final Key key, final PointerTracker tracker) { final MoreKeysPanel moreKeysPanel = onCreateMoreKeysPanel(key, getContext()); if (moreKeysPanel == null) { diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 7b14259a0..53207597a 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -175,7 +175,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private DrawingProxy mDrawingProxy; private TimerProxy mTimerProxy; private KeyDetector mKeyDetector; - private KeyboardActionListener mListener = KeyboardActionListener.Adapter.EMPTY_LISTENER; + private KeyboardActionListener mListener = KeyboardActionListener.EMPTY_LISTENER; private Keyboard mKeyboard; private int mPhantonSuddenMoveThreshold; @@ -1263,13 +1263,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (!key.isRepeatable()) return; // Don't start key repeat when we are in sliding input mode. if (mIsInSlidingKeyInput) return; - onRepeatKey(key); - mTimerProxy.startKeyRepeatTimer(this); - } - - public void onRepeatKey(final Key key) { detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis()); - mTimerProxy.startTypingStateTimer(key); + mTimerProxy.startKeyRepeatTimer(this); } private boolean isMajorEnoughMoveToBeOnNewKey(final int x, final int y, final long eventTime, diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java index 370d0cb93..8ead44c31 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java @@ -81,9 +81,6 @@ public final class KeyboardState { private boolean mPrevSymbolsKeyboardWasShifted; private int mRecapitalizeMode; - // For handling long press. - private boolean mLongPressShiftLockFired; - // For handling double tap. private boolean mIsInAlphabetUnshiftedFromShifted; private boolean mIsInDoubleTapShiftKey; @@ -325,10 +322,11 @@ public final class KeyboardState { } if (code == Constants.CODE_SHIFT) { onPressShift(); + } else if (code == Constants.CODE_CAPSLOCK) { + // Nothing to do here. See {@link #onReleaseKey(int,boolean)}. } else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { onPressSymbol(); } else { - mLongPressShiftLockFired = false; mShiftKeyState.onOtherKeyPressed(); mSymbolKeyState.onOtherKeyPressed(); // It is required to reset the auto caps state when all of the following conditions @@ -356,6 +354,8 @@ public final class KeyboardState { } if (code == Constants.CODE_SHIFT) { onReleaseShift(withSliding); + } else if (code == Constants.CODE_CAPSLOCK) { + setShiftLocked(!mAlphabetShiftState.isShiftLocked()); } else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { onReleaseSymbol(withSliding); } @@ -437,7 +437,6 @@ public final class KeyboardState { } private void onPressShift() { - mLongPressShiftLockFired = false; // If we are recapitalizing, we don't do any of the normal processing, including // importantly the double tap timer. if (RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE != mRecapitalizeMode) { @@ -499,8 +498,6 @@ public final class KeyboardState { // Double tap shift key has been handled in {@link #onPressShift}, so that just // ignore this release shift key here. mIsInDoubleTapShiftKey = false; - } else if (mLongPressShiftLockFired) { - setShiftLocked(!mAlphabetShiftState.isShiftLocked()); } else if (mShiftKeyState.isChording()) { if (mAlphabetShiftState.isShiftLockShifted()) { // After chording input while shift locked state. @@ -610,12 +607,6 @@ public final class KeyboardState { break; } - if (code == Constants.CODE_CAPSLOCK) { - // Changing shift lock state will be handled at {@link #onPressShift()} when the shift - // key is released. - mLongPressShiftLockFired = true; - } - // If the code is a letter, update keyboard shift state. if (Constants.isLetterCode(code)) { updateAlphabetShiftState(autoCaps, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE); diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java index bb4a42ede..ad09b6a56 100644 --- a/java/src/com/android/inputmethod/latin/Constants.java +++ b/java/src/com/android/inputmethod/latin/Constants.java @@ -148,6 +148,13 @@ public final class Constants { return coordinate >= 0; } + /** + * Custom request code used in + * {@link com.android.inputmethod.keyboard.KeyboardActionListener#onCustomRequest(int)}. + */ + // The code to show input method picker. + public static final int CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER = 1; + /** * Some common keys code. Must be positive. */ diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 243928f8b..f4f9dcc50 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1360,14 +1360,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen showSubtypeSelectorAndSettings(); } - // Virtual codes representing custom requests. These are used in onCustomRequest() below. - public static final int CODE_SHOW_INPUT_METHOD_PICKER = 1; - @Override public boolean onCustomRequest(final int requestCode) { if (isShowingOptionDialog()) return false; switch (requestCode) { - case CODE_SHOW_INPUT_METHOD_PICKER: + case Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER: if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { mRichImm.getInputMethodManager().showInputMethodPicker(); return true; @@ -2678,15 +2675,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } - // Callback called by PointerTracker through the KeyboardActionListener. This is called when a - // key is depressed; release matching call is onReleaseKey below. + // Callback of the {@link KeyboardActionListener}. This is called when a key is depressed; + // release matching call is {@link #onReleaseKey(int,boolean)} below. @Override public void onPressKey(final int primaryCode, final boolean isSinglePointer) { mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer); + final MainKeyboardView mKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); + final boolean noFeedback = (mKeyboardView != null && mKeyboardView.isInSlidingKeyInput()) + || (primaryCode == Constants.CODE_DELETE && !mConnection.canDeleteCharacters()); + if (!noFeedback) { + AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback( + primaryCode, mKeyboardView); + } } - // Callback by PointerTracker through the KeyboardActionListener. This is called when a key - // is released; press matching call is onPressKey above. + // Callback of the {@link KeyboardActionListener}. This is called when a key is released; + // press matching call is {@link #onPressKey(int,boolean)} above. @Override public void onReleaseKey(final int primaryCode, final boolean withSliding) { mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding); diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 39170cf38..461de53ad 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -191,6 +191,10 @@ public final class RichInputConnection { return mIC.getSelectedText(flags); } + public boolean canDeleteCharacters() { + return mCurrentCursorPosition > 0; + } + /** * Gets the caps modes we should be in after this specific string. * -- cgit v1.2.3-83-g751a