Loading java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -26,10 +26,10 @@ public interface KeyboardActionListener { * * * @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key, * @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key, * the value will be zero. * the value will be zero. * @param isRepeatKey true if pressing has occurred while key repeat input. * @param repeatCount how many times the key was repeated. Zero if it is the first press. * @param isSinglePointer true if pressing has occurred while no other key is being pressed. * @param isSinglePointer true if pressing has occurred while no other key is being pressed. */ */ public void onPressKey(int primaryCode, boolean isRepeatKey, boolean isSinglePointer); public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer); /** /** * Called when the user releases a key. This is sent after the {@link #onCodeInput} is called. * Called when the user releases a key. This is sent after the {@link #onCodeInput} is called. Loading Loading @@ -103,7 +103,7 @@ public interface KeyboardActionListener { public static class Adapter implements KeyboardActionListener { public static class Adapter implements KeyboardActionListener { @Override @Override public void onPressKey(int primaryCode, boolean isRepeatKey, boolean isSinglePointer) {} public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer) {} @Override @Override public void onReleaseKey(int primaryCode, boolean withSliding) {} public void onReleaseKey(int primaryCode, boolean withSliding) {} @Override @Override Loading java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +6 −4 Original line number Original line Diff line number Diff line Loading @@ -217,7 +217,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack startWhileTypingFadeinAnimation(keyboardView); startWhileTypingFadeinAnimation(keyboardView); break; break; case MSG_REPEAT_KEY: case MSG_REPEAT_KEY: tracker.onKeyRepeat(msg.arg1); tracker.onKeyRepeat(msg.arg1 /* code */, msg.arg2 /* repeatCount */); break; break; case MSG_LONGPRESS_KEY: case MSG_LONGPRESS_KEY: keyboardView.onLongPress(tracker); keyboardView.onLongPress(tracker); Loading @@ -230,12 +230,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack } } @Override @Override public void startKeyRepeatTimer(final PointerTracker tracker, final int delay) { public void startKeyRepeatTimer(final PointerTracker tracker, final int repeatCount, final int delay) { final Key key = tracker.getKey(); final Key key = tracker.getKey(); if (key == null || delay == 0) { if (key == null || delay == 0) { return; return; } } sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay); sendMessageDelayed( obtainMessage(MSG_REPEAT_KEY, key.mCode, repeatCount, tracker), delay); } } public void cancelKeyRepeatTimer() { public void cancelKeyRepeatTimer() { Loading Loading @@ -938,7 +940,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack if (key.hasNoPanelAutoMoreKey()) { if (key.hasNoPanelAutoMoreKey()) { final int moreKeyCode = key.mMoreKeys[0].mCode; final int moreKeyCode = key.mMoreKeys[0].mCode; tracker.onLongPressed(); tracker.onLongPressed(); listener.onPressKey(moreKeyCode, false /* isRepeatKey */, true /* isSinglePointer */); listener.onPressKey(moreKeyCode, 0 /* repeatCount */, true /* isSinglePointer */); listener.onCodeInput(moreKeyCode, listener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); listener.onReleaseKey(moreKeyCode, false /* withSliding */); listener.onReleaseKey(moreKeyCode, false /* withSliding */); Loading java/src/com/android/inputmethod/keyboard/PointerTracker.java +14 −12 Original line number Original line Diff line number Diff line Loading @@ -64,7 +64,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { /** /** * Get KeyboardActionListener object that is used to register key code and so on. * Get KeyboardActionListener object that is used to register key code and so on. * @return the KeyboardActionListner for this PointerTracker * @return the KeyboardActionListner for this PointerTracke */ */ public KeyboardActionListener getKeyboardActionListener(); public KeyboardActionListener getKeyboardActionListener(); Loading Loading @@ -94,7 +94,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { public interface TimerProxy { public interface TimerProxy { public void startTypingStateTimer(Key typedKey); public void startTypingStateTimer(Key typedKey); public boolean isTypingState(); public boolean isTypingState(); public void startKeyRepeatTimer(PointerTracker tracker, int delay); public void startKeyRepeatTimer(PointerTracker tracker, int repeatCount, int delay); public void startLongPressTimer(PointerTracker tracker, int delay); public void startLongPressTimer(PointerTracker tracker, int delay); public void cancelLongPressTimer(); public void cancelLongPressTimer(); public void startDoubleTapShiftKeyTimer(); public void startDoubleTapShiftKeyTimer(); Loading @@ -111,7 +111,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { @Override @Override public boolean isTypingState() { return false; } public boolean isTypingState() { return false; } @Override @Override public void startKeyRepeatTimer(PointerTracker tracker, int delay) {} public void startKeyRepeatTimer(PointerTracker tracker, int repeatCount, int delay) {} @Override @Override public void startLongPressTimer(PointerTracker tracker, int delay) {} public void startLongPressTimer(PointerTracker tracker, int delay) {} @Override @Override Loading Loading @@ -490,7 +490,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Returns true if keyboard has been changed by this callback. // Returns true if keyboard has been changed by this callback. private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key, private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key, final boolean isRepeatKey) { final int repeatCount) { // While gesture input is going on, this method should be a no-operation. But when gesture // While gesture input is going on, this method should be a no-operation. But when gesture // input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code> // input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code> // are set to false. To keep this method is a no-operation, // are set to false. To keep this method is a no-operation, Loading @@ -504,13 +504,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { KeyDetector.printableCode(key), KeyDetector.printableCode(key), ignoreModifierKey ? " ignoreModifier" : "", ignoreModifierKey ? " ignoreModifier" : "", key.isEnabled() ? "" : " disabled", key.isEnabled() ? "" : " disabled", isRepeatKey ? " repeat" : "")); repeatCount > 0 ? " repeatCount=" + repeatCount : "")); } } if (ignoreModifierKey) { if (ignoreModifierKey) { return false; return false; } } if (key.isEnabled()) { if (key.isEnabled()) { mListener.onPressKey(key.mCode, isRepeatKey, getActivePointerTrackerCount() == 1); mListener.onPressKey(key.mCode, repeatCount, getActivePointerTrackerCount() == 1); final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; mKeyboardLayoutHasBeenChanged = false; mKeyboardLayoutHasBeenChanged = false; mTimerProxy.startTypingStateTimer(key); mTimerProxy.startTypingStateTimer(key); Loading Loading @@ -967,7 +967,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // This onPress call may have changed keyboard layout. Those cases are detected at // This onPress call may have changed keyboard layout. Those cases are detected at // {@link #setKeyboard}. In those cases, we should update key according to the new // {@link #setKeyboard}. In those cases, we should update key according to the new // keyboard layout. // keyboard layout. if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false /* isRepeatKey */)) { if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) { key = onDownKey(x, y, eventTime); key = onDownKey(x, y, eventTime); } } Loading Loading @@ -1057,7 +1057,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // at {@link #setKeyboard}. In those cases, we should update key according // at {@link #setKeyboard}. In those cases, we should update key according // to the new keyboard layout. // to the new keyboard layout. Key key = newKey; Key key = newKey; if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false /* isRepeatKey */)) { if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) { key = onMoveKey(x, y); key = onMoveKey(x, y); } } onMoveToNewKey(key, x, y); onMoveToNewKey(key, x, y); Loading Loading @@ -1413,16 +1413,18 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Don't start key repeat when we are in sliding input mode. // Don't start key repeat when we are in sliding input mode. if (mIsInSlidingKeyInput) return; if (mIsInSlidingKeyInput) return; detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis()); detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis()); mTimerProxy.startKeyRepeatTimer(this, sParams.mKeyRepeatStartTimeout); final int startRepeatCount = 1; mTimerProxy.startKeyRepeatTimer(this, startRepeatCount, sParams.mKeyRepeatStartTimeout); } } public void onKeyRepeat(final int code) { public void onKeyRepeat(final int code, final int repeatCount) { final Key key = getKey(); final Key key = getKey(); if (key == null || key.mCode != code) { if (key == null || key.mCode != code) { return; return; } } mTimerProxy.startKeyRepeatTimer(this, sParams.mKeyRepeatInterval); final int nextRepeatCount = repeatCount + 1; callListenerOnPressAndCheckKeyboardLayoutChange(key, true /* isRepeatKey */); mTimerProxy.startKeyRepeatTimer(this, nextRepeatCount, sParams.mKeyRepeatInterval); callListenerOnPressAndCheckKeyboardLayoutChange(key, repeatCount); callListenerOnCodeInput(key, code, mKeyX, mKeyY, SystemClock.uptimeMillis()); callListenerOnCodeInput(key, code, mKeyX, mKeyY, SystemClock.uptimeMillis()); } } Loading java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java +6 −6 Original line number Original line Diff line number Diff line Loading @@ -57,10 +57,10 @@ public final class AudioAndHapticFeedbackManager { mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); } } public void hapticAndAudioFeedback(final int primaryCode, public void performHapticAndAudioFeedback(final int code, final View viewToPerformHapticFeedbackOn) { final View viewToPerformHapticFeedbackOn) { vibrateInternal(viewToPerformHapticFeedbackOn); performHapticFeedback(viewToPerformHapticFeedbackOn); playKeyClick(primaryCode); performAudioFeedback(code); } } public boolean hasVibrator() { public boolean hasVibrator() { Loading @@ -81,14 +81,14 @@ public final class AudioAndHapticFeedbackManager { return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL; return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL; } } private void playKeyClick(final int primaryCode) { public void performAudioFeedback(final int code) { // if mAudioManager is null, we can't play a sound anyway, so return // if mAudioManager is null, we can't play a sound anyway, so return if (mAudioManager == null) { if (mAudioManager == null) { return; return; } } if (mSoundOn) { if (mSoundOn) { final int sound; final int sound; switch (primaryCode) { switch (code) { case Constants.CODE_DELETE: case Constants.CODE_DELETE: sound = AudioManager.FX_KEYPRESS_DELETE; sound = AudioManager.FX_KEYPRESS_DELETE; break; break; Loading @@ -106,7 +106,7 @@ public final class AudioAndHapticFeedbackManager { } } } } private void vibrateInternal(final View viewToPerformHapticFeedbackOn) { public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) { if (!mSettingsValues.mVibrateOn) { if (!mSettingsValues.mVibrateOn) { return; return; } } Loading java/src/com/android/inputmethod/latin/LatinIME.java +25 −10 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int PENDING_IMS_CALLBACK_DURATION = 800; private static final int PENDING_IMS_CALLBACK_DURATION = 800; private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2; /** /** * The name of the scheme used by the Package Manager to warn of a new package installation, * The name of the scheme used by the Package Manager to warn of a new package installation, * replacement or removal. * replacement or removal. Loading Loading @@ -1462,7 +1464,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; break; case Constants.CODE_SHIFT: case Constants.CODE_SHIFT: // Note: Calling back to the keyboard on Shift key is handled in // Note: Calling back to the keyboard on Shift key is handled in // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}. // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. final Keyboard currentKeyboard = switcher.getKeyboard(); final Keyboard currentKeyboard = switcher.getKeyboard(); if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for Loading @@ -1476,7 +1478,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; break; case Constants.CODE_SWITCH_ALPHA_SYMBOL: case Constants.CODE_SWITCH_ALPHA_SYMBOL: // Note: Calling back to the keyboard on symbol key is handled in // Note: Calling back to the keyboard on symbol key is handled in // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}. // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. break; break; case Constants.CODE_SETTINGS: case Constants.CODE_SETTINGS: onSettingsKeyPressed(); onSettingsKeyPressed(); Loading Loading @@ -2698,30 +2700,43 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } } } private void hapticAndAudioFeedback(final int code, final boolean isRepeatKey) { private void hapticAndAudioFeedback(final int code, final int repeatCount) { final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView(); if (keyboardView != null && keyboardView.isInSlidingKeyInput()) { if (keyboardView != null && keyboardView.isInSlidingKeyInput()) { // No need to feedback while sliding input. // No need to feedback while sliding input. return; return; } } if (isRepeatKey) { if (repeatCount > 0) { // No need to feedback when repeating key. if (code == Constants.CODE_DELETE && !mConnection.canDeleteCharacters()) { // No need to feedback when repeat delete key will have no effect. return; } // TODO: Use event time that the last feedback has been generated instead of relying on // a repeat count to thin out feedback. if (repeatCount % PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT == 0) { return; return; } } AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(code, keyboardView); } final AudioAndHapticFeedbackManager feedbackManager = AudioAndHapticFeedbackManager.getInstance(); if (repeatCount == 0) { // TODO: Reconsider how to perform haptic feedback when repeating key. feedbackManager.performHapticFeedback(keyboardView); } feedbackManager.performAudioFeedback(code); } } // Callback of the {@link KeyboardActionListener}. This is called when a key is depressed; // Callback of the {@link KeyboardActionListener}. This is called when a key is depressed; // release matching call is {@link #onReleaseKey(int,boolean)} below. // release matching call is {@link #onReleaseKey(int,boolean)} below. @Override @Override public void onPressKey(final int primaryCode, final boolean isRepeatKey, public void onPressKey(final int primaryCode, final int repeatCount, final boolean isSinglePointer) { final boolean isSinglePointer) { mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer); mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer); hapticAndAudioFeedback(primaryCode, isRepeatKey); hapticAndAudioFeedback(primaryCode, repeatCount); } } // Callback of the {@link KeyboardActionListener}. This is called when a key is released; // Callback of the {@link KeyboardActionListener}. This is called when a key is released; // press matching call is {@link #onPressKey(int,boolean,boolean)} above. // press matching call is {@link #onPressKey(int,int,boolean)} above. @Override @Override public void onReleaseKey(final int primaryCode, final boolean withSliding) { public void onReleaseKey(final int primaryCode, final boolean withSliding) { mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding); mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding); Loading Loading
java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -26,10 +26,10 @@ public interface KeyboardActionListener { * * * @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key, * @param primaryCode the unicode of the key being pressed. If the touch is not on a valid key, * the value will be zero. * the value will be zero. * @param isRepeatKey true if pressing has occurred while key repeat input. * @param repeatCount how many times the key was repeated. Zero if it is the first press. * @param isSinglePointer true if pressing has occurred while no other key is being pressed. * @param isSinglePointer true if pressing has occurred while no other key is being pressed. */ */ public void onPressKey(int primaryCode, boolean isRepeatKey, boolean isSinglePointer); public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer); /** /** * Called when the user releases a key. This is sent after the {@link #onCodeInput} is called. * Called when the user releases a key. This is sent after the {@link #onCodeInput} is called. Loading Loading @@ -103,7 +103,7 @@ public interface KeyboardActionListener { public static class Adapter implements KeyboardActionListener { public static class Adapter implements KeyboardActionListener { @Override @Override public void onPressKey(int primaryCode, boolean isRepeatKey, boolean isSinglePointer) {} public void onPressKey(int primaryCode, int repeatCount, boolean isSinglePointer) {} @Override @Override public void onReleaseKey(int primaryCode, boolean withSliding) {} public void onReleaseKey(int primaryCode, boolean withSliding) {} @Override @Override Loading
java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +6 −4 Original line number Original line Diff line number Diff line Loading @@ -217,7 +217,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack startWhileTypingFadeinAnimation(keyboardView); startWhileTypingFadeinAnimation(keyboardView); break; break; case MSG_REPEAT_KEY: case MSG_REPEAT_KEY: tracker.onKeyRepeat(msg.arg1); tracker.onKeyRepeat(msg.arg1 /* code */, msg.arg2 /* repeatCount */); break; break; case MSG_LONGPRESS_KEY: case MSG_LONGPRESS_KEY: keyboardView.onLongPress(tracker); keyboardView.onLongPress(tracker); Loading @@ -230,12 +230,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack } } @Override @Override public void startKeyRepeatTimer(final PointerTracker tracker, final int delay) { public void startKeyRepeatTimer(final PointerTracker tracker, final int repeatCount, final int delay) { final Key key = tracker.getKey(); final Key key = tracker.getKey(); if (key == null || delay == 0) { if (key == null || delay == 0) { return; return; } } sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay); sendMessageDelayed( obtainMessage(MSG_REPEAT_KEY, key.mCode, repeatCount, tracker), delay); } } public void cancelKeyRepeatTimer() { public void cancelKeyRepeatTimer() { Loading Loading @@ -938,7 +940,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack if (key.hasNoPanelAutoMoreKey()) { if (key.hasNoPanelAutoMoreKey()) { final int moreKeyCode = key.mMoreKeys[0].mCode; final int moreKeyCode = key.mMoreKeys[0].mCode; tracker.onLongPressed(); tracker.onLongPressed(); listener.onPressKey(moreKeyCode, false /* isRepeatKey */, true /* isSinglePointer */); listener.onPressKey(moreKeyCode, 0 /* repeatCount */, true /* isSinglePointer */); listener.onCodeInput(moreKeyCode, listener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); listener.onReleaseKey(moreKeyCode, false /* withSliding */); listener.onReleaseKey(moreKeyCode, false /* withSliding */); Loading
java/src/com/android/inputmethod/keyboard/PointerTracker.java +14 −12 Original line number Original line Diff line number Diff line Loading @@ -64,7 +64,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { /** /** * Get KeyboardActionListener object that is used to register key code and so on. * Get KeyboardActionListener object that is used to register key code and so on. * @return the KeyboardActionListner for this PointerTracker * @return the KeyboardActionListner for this PointerTracke */ */ public KeyboardActionListener getKeyboardActionListener(); public KeyboardActionListener getKeyboardActionListener(); Loading Loading @@ -94,7 +94,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { public interface TimerProxy { public interface TimerProxy { public void startTypingStateTimer(Key typedKey); public void startTypingStateTimer(Key typedKey); public boolean isTypingState(); public boolean isTypingState(); public void startKeyRepeatTimer(PointerTracker tracker, int delay); public void startKeyRepeatTimer(PointerTracker tracker, int repeatCount, int delay); public void startLongPressTimer(PointerTracker tracker, int delay); public void startLongPressTimer(PointerTracker tracker, int delay); public void cancelLongPressTimer(); public void cancelLongPressTimer(); public void startDoubleTapShiftKeyTimer(); public void startDoubleTapShiftKeyTimer(); Loading @@ -111,7 +111,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { @Override @Override public boolean isTypingState() { return false; } public boolean isTypingState() { return false; } @Override @Override public void startKeyRepeatTimer(PointerTracker tracker, int delay) {} public void startKeyRepeatTimer(PointerTracker tracker, int repeatCount, int delay) {} @Override @Override public void startLongPressTimer(PointerTracker tracker, int delay) {} public void startLongPressTimer(PointerTracker tracker, int delay) {} @Override @Override Loading Loading @@ -490,7 +490,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Returns true if keyboard has been changed by this callback. // Returns true if keyboard has been changed by this callback. private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key, private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key, final boolean isRepeatKey) { final int repeatCount) { // While gesture input is going on, this method should be a no-operation. But when gesture // While gesture input is going on, this method should be a no-operation. But when gesture // input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code> // input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code> // are set to false. To keep this method is a no-operation, // are set to false. To keep this method is a no-operation, Loading @@ -504,13 +504,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { KeyDetector.printableCode(key), KeyDetector.printableCode(key), ignoreModifierKey ? " ignoreModifier" : "", ignoreModifierKey ? " ignoreModifier" : "", key.isEnabled() ? "" : " disabled", key.isEnabled() ? "" : " disabled", isRepeatKey ? " repeat" : "")); repeatCount > 0 ? " repeatCount=" + repeatCount : "")); } } if (ignoreModifierKey) { if (ignoreModifierKey) { return false; return false; } } if (key.isEnabled()) { if (key.isEnabled()) { mListener.onPressKey(key.mCode, isRepeatKey, getActivePointerTrackerCount() == 1); mListener.onPressKey(key.mCode, repeatCount, getActivePointerTrackerCount() == 1); final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; mKeyboardLayoutHasBeenChanged = false; mKeyboardLayoutHasBeenChanged = false; mTimerProxy.startTypingStateTimer(key); mTimerProxy.startTypingStateTimer(key); Loading Loading @@ -967,7 +967,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // This onPress call may have changed keyboard layout. Those cases are detected at // This onPress call may have changed keyboard layout. Those cases are detected at // {@link #setKeyboard}. In those cases, we should update key according to the new // {@link #setKeyboard}. In those cases, we should update key according to the new // keyboard layout. // keyboard layout. if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false /* isRepeatKey */)) { if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) { key = onDownKey(x, y, eventTime); key = onDownKey(x, y, eventTime); } } Loading Loading @@ -1057,7 +1057,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // at {@link #setKeyboard}. In those cases, we should update key according // at {@link #setKeyboard}. In those cases, we should update key according // to the new keyboard layout. // to the new keyboard layout. Key key = newKey; Key key = newKey; if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false /* isRepeatKey */)) { if (callListenerOnPressAndCheckKeyboardLayoutChange(key, 0 /* repeatCount */)) { key = onMoveKey(x, y); key = onMoveKey(x, y); } } onMoveToNewKey(key, x, y); onMoveToNewKey(key, x, y); Loading Loading @@ -1413,16 +1413,18 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Don't start key repeat when we are in sliding input mode. // Don't start key repeat when we are in sliding input mode. if (mIsInSlidingKeyInput) return; if (mIsInSlidingKeyInput) return; detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis()); detectAndSendKey(key, key.mX, key.mY, SystemClock.uptimeMillis()); mTimerProxy.startKeyRepeatTimer(this, sParams.mKeyRepeatStartTimeout); final int startRepeatCount = 1; mTimerProxy.startKeyRepeatTimer(this, startRepeatCount, sParams.mKeyRepeatStartTimeout); } } public void onKeyRepeat(final int code) { public void onKeyRepeat(final int code, final int repeatCount) { final Key key = getKey(); final Key key = getKey(); if (key == null || key.mCode != code) { if (key == null || key.mCode != code) { return; return; } } mTimerProxy.startKeyRepeatTimer(this, sParams.mKeyRepeatInterval); final int nextRepeatCount = repeatCount + 1; callListenerOnPressAndCheckKeyboardLayoutChange(key, true /* isRepeatKey */); mTimerProxy.startKeyRepeatTimer(this, nextRepeatCount, sParams.mKeyRepeatInterval); callListenerOnPressAndCheckKeyboardLayoutChange(key, repeatCount); callListenerOnCodeInput(key, code, mKeyX, mKeyY, SystemClock.uptimeMillis()); callListenerOnCodeInput(key, code, mKeyX, mKeyY, SystemClock.uptimeMillis()); } } Loading
java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java +6 −6 Original line number Original line Diff line number Diff line Loading @@ -57,10 +57,10 @@ public final class AudioAndHapticFeedbackManager { mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); } } public void hapticAndAudioFeedback(final int primaryCode, public void performHapticAndAudioFeedback(final int code, final View viewToPerformHapticFeedbackOn) { final View viewToPerformHapticFeedbackOn) { vibrateInternal(viewToPerformHapticFeedbackOn); performHapticFeedback(viewToPerformHapticFeedbackOn); playKeyClick(primaryCode); performAudioFeedback(code); } } public boolean hasVibrator() { public boolean hasVibrator() { Loading @@ -81,14 +81,14 @@ public final class AudioAndHapticFeedbackManager { return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL; return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL; } } private void playKeyClick(final int primaryCode) { public void performAudioFeedback(final int code) { // if mAudioManager is null, we can't play a sound anyway, so return // if mAudioManager is null, we can't play a sound anyway, so return if (mAudioManager == null) { if (mAudioManager == null) { return; return; } } if (mSoundOn) { if (mSoundOn) { final int sound; final int sound; switch (primaryCode) { switch (code) { case Constants.CODE_DELETE: case Constants.CODE_DELETE: sound = AudioManager.FX_KEYPRESS_DELETE; sound = AudioManager.FX_KEYPRESS_DELETE; break; break; Loading @@ -106,7 +106,7 @@ public final class AudioAndHapticFeedbackManager { } } } } private void vibrateInternal(final View viewToPerformHapticFeedbackOn) { public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) { if (!mSettingsValues.mVibrateOn) { if (!mSettingsValues.mVibrateOn) { return; return; } } Loading
java/src/com/android/inputmethod/latin/LatinIME.java +25 −10 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int PENDING_IMS_CALLBACK_DURATION = 800; private static final int PENDING_IMS_CALLBACK_DURATION = 800; private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2; /** /** * The name of the scheme used by the Package Manager to warn of a new package installation, * The name of the scheme used by the Package Manager to warn of a new package installation, * replacement or removal. * replacement or removal. Loading Loading @@ -1462,7 +1464,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; break; case Constants.CODE_SHIFT: case Constants.CODE_SHIFT: // Note: Calling back to the keyboard on Shift key is handled in // Note: Calling back to the keyboard on Shift key is handled in // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}. // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. final Keyboard currentKeyboard = switcher.getKeyboard(); final Keyboard currentKeyboard = switcher.getKeyboard(); if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for Loading @@ -1476,7 +1478,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen break; break; case Constants.CODE_SWITCH_ALPHA_SYMBOL: case Constants.CODE_SWITCH_ALPHA_SYMBOL: // Note: Calling back to the keyboard on symbol key is handled in // Note: Calling back to the keyboard on symbol key is handled in // {@link #onPressKey(int,boolean)} and {@link #onReleaseKey(int,boolean)}. // {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. break; break; case Constants.CODE_SETTINGS: case Constants.CODE_SETTINGS: onSettingsKeyPressed(); onSettingsKeyPressed(); Loading Loading @@ -2698,30 +2700,43 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } } } private void hapticAndAudioFeedback(final int code, final boolean isRepeatKey) { private void hapticAndAudioFeedback(final int code, final int repeatCount) { final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView(); if (keyboardView != null && keyboardView.isInSlidingKeyInput()) { if (keyboardView != null && keyboardView.isInSlidingKeyInput()) { // No need to feedback while sliding input. // No need to feedback while sliding input. return; return; } } if (isRepeatKey) { if (repeatCount > 0) { // No need to feedback when repeating key. if (code == Constants.CODE_DELETE && !mConnection.canDeleteCharacters()) { // No need to feedback when repeat delete key will have no effect. return; } // TODO: Use event time that the last feedback has been generated instead of relying on // a repeat count to thin out feedback. if (repeatCount % PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT == 0) { return; return; } } AudioAndHapticFeedbackManager.getInstance().hapticAndAudioFeedback(code, keyboardView); } final AudioAndHapticFeedbackManager feedbackManager = AudioAndHapticFeedbackManager.getInstance(); if (repeatCount == 0) { // TODO: Reconsider how to perform haptic feedback when repeating key. feedbackManager.performHapticFeedback(keyboardView); } feedbackManager.performAudioFeedback(code); } } // Callback of the {@link KeyboardActionListener}. This is called when a key is depressed; // Callback of the {@link KeyboardActionListener}. This is called when a key is depressed; // release matching call is {@link #onReleaseKey(int,boolean)} below. // release matching call is {@link #onReleaseKey(int,boolean)} below. @Override @Override public void onPressKey(final int primaryCode, final boolean isRepeatKey, public void onPressKey(final int primaryCode, final int repeatCount, final boolean isSinglePointer) { final boolean isSinglePointer) { mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer); mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer); hapticAndAudioFeedback(primaryCode, isRepeatKey); hapticAndAudioFeedback(primaryCode, repeatCount); } } // Callback of the {@link KeyboardActionListener}. This is called when a key is released; // Callback of the {@link KeyboardActionListener}. This is called when a key is released; // press matching call is {@link #onPressKey(int,boolean,boolean)} above. // press matching call is {@link #onPressKey(int,int,boolean)} above. @Override @Override public void onReleaseKey(final int primaryCode, final boolean withSliding) { public void onReleaseKey(final int primaryCode, final boolean withSliding) { mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding); mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding); Loading