diff options
Diffstat (limited to 'java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java')
-rw-r--r-- | java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java | 123 |
1 files changed, 90 insertions, 33 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index 0043b7844..d2031d155 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -18,6 +18,7 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.inputmethodservice.InputMethodService; +import android.os.SystemClock; import android.support.v4.view.AccessibilityDelegateCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.accessibility.AccessibilityEventCompat; @@ -34,6 +35,7 @@ import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.MainKeyboardView; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy(); @@ -55,6 +57,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp private InputMethodService mInputMethod; private MainKeyboardView mView; + private Keyboard mKeyboard; private AccessibilityEntityProvider mAccessibilityNodeProvider; private Key mLastHoverKey = null; @@ -65,7 +68,8 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp private int mEdgeSlop; /** The most recently set keyboard mode. */ - private int mLastKeyboardMode; + private int mLastKeyboardMode = KEYBOARD_IS_HIDDEN; + private static final int KEYBOARD_IS_HIDDEN = -1; public static void init(final InputMethodService inputMethod) { sInstance.initInternal(inputMethod); @@ -104,6 +108,10 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp return; } mAccessibilityNodeProvider.setView(view); + + // Since this class is constructed lazily, we might not get a subsequent + // call to setKeyboard() and therefore need to call it now. + setKeyboard(view.getKeyboard()); } /** @@ -111,24 +119,33 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp * <p> * <b>Note:</b> This method will be called even if accessibility is not * enabled. + * @param keyboard The keyboard that is being set to the wrapping view. */ - public void setKeyboard() { - if (mView == null) { + public void setKeyboard(final Keyboard keyboard) { + if (keyboard == null) { return; } if (mAccessibilityNodeProvider != null) { - mAccessibilityNodeProvider.setKeyboard(); + mAccessibilityNodeProvider.setKeyboard(keyboard); } - final int keyboardMode = mView.getKeyboard().mId.mMode; + final Keyboard lastKeyboard = mKeyboard; + final int lastKeyboardMode = mLastKeyboardMode; + mKeyboard = keyboard; + mLastKeyboardMode = keyboard.mId.mMode; // Since this method is called even when accessibility is off, make sure - // to check the state before announcing anything. Also, don't announce - // changes within the same mode. - if (AccessibilityUtils.getInstance().isAccessibilityEnabled() - && (mLastKeyboardMode != keyboardMode)) { - announceKeyboardMode(keyboardMode); + // to check the state before announcing anything. + if (!AccessibilityUtils.getInstance().isAccessibilityEnabled()) { + return; + } + // Announce the language name only when the language is changed. + if (lastKeyboard == null || !lastKeyboard.mId.mSubtype.equals(keyboard.mId.mSubtype)) { + announceKeyboardLanguage(keyboard); + } + // Announce the mode only when the mode is changed. + if (lastKeyboardMode != keyboard.mId.mMode) { + announceKeyboardMode(keyboard); } - mLastKeyboardMode = keyboardMode; } /** @@ -139,23 +156,35 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp return; } announceKeyboardHidden(); - mLastKeyboardMode = -1; + mLastKeyboardMode = KEYBOARD_IS_HIDDEN; } /** - * Announces which type of keyboard is being displayed. If the keyboard type - * is unknown, no announcement is made. + * Announces which language of keyboard is being displayed. * - * @param mode The new keyboard mode. + * @param keyboard The new keyboard. */ - private void announceKeyboardMode(int mode) { - final int resId = KEYBOARD_MODE_RES_IDS.get(mode); - if (resId == 0) { + private void announceKeyboardLanguage(final Keyboard keyboard) { + final String languageText = SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale( + keyboard.mId.mSubtype); + sendWindowStateChanged(languageText); + } + + /** + * Announces which type of keyboard is being displayed. + * If the keyboard type is unknown, no announcement is made. + * + * @param keyboard The new keyboard. + */ + private void announceKeyboardMode(final Keyboard keyboard) { + final int mode = keyboard.mId.mMode; + final Context context = mView.getContext(); + final int modeTextResId = KEYBOARD_MODE_RES_IDS.get(mode); + if (modeTextResId == 0) { return; } - final Context context = mView.getContext(); - final String keyboardMode = context.getString(resId); - final String text = context.getString(R.string.announce_keyboard_mode, keyboardMode); + final String modeText = context.getString(modeTextResId); + final String text = context.getString(R.string.announce_keyboard_mode, modeText); sendWindowStateChanged(text); } @@ -233,7 +262,8 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp // Make sure we're not getting an EXIT event because the user slid // off the keyboard area, then force a key press. if (key != null) { - getAccessibilityNodeProvider().simulateKeyPress(key); + final long downTime = simulateKeyPress(key); + simulateKeyRelease(key, downTime); } //$FALL-THROUGH$ case MotionEvent.ACTION_HOVER_ENTER: @@ -274,6 +304,38 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp } /** + * Simulates a key press by injecting touch event into the keyboard view. + * This avoids the complexity of trackers and listeners within the keyboard. + * + * @param key The key to press. + */ + private long simulateKeyPress(final Key key) { + final int x = key.getHitBox().centerX(); + final int y = key.getHitBox().centerY(); + final long downTime = SystemClock.uptimeMillis(); + final MotionEvent downEvent = MotionEvent.obtain( + downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0); + mView.onTouchEvent(downEvent); + downEvent.recycle(); + return downTime; + } + + /** + * Simulates a key release by injecting touch event into the keyboard view. + * This avoids the complexity of trackers and listeners within the keyboard. + * + * @param key The key to release. + */ + private void simulateKeyRelease(final Key key, final long downTime) { + final int x = key.getHitBox().centerX(); + final int y = key.getHitBox().centerY(); + final MotionEvent upEvent = MotionEvent.obtain( + downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0); + mView.onTouchEvent(upEvent); + upEvent.recycle(); + } + + /** * Simulates a transition between two {@link Key}s by sending a HOVER_EXIT on the previous key, * a HOVER_ENTER on the current key, and a HOVER_MOVE on the current key. * @@ -329,12 +391,11 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp * Notifies the user of changes in the keyboard shift state. */ public void notifyShiftState() { - if (mView == null) { + if (mView == null || mKeyboard == null) { return; } - final Keyboard keyboard = mView.getKeyboard(); - final KeyboardId keyboardId = keyboard.mId; + final KeyboardId keyboardId = mKeyboard.mId; final int elementId = keyboardId.mElementId; final Context context = mView.getContext(); final CharSequence text; @@ -359,14 +420,13 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp * Notifies the user of changes in the keyboard symbols state. */ public void notifySymbolsState() { - if (mView == null) { + if (mView == null || mKeyboard == null) { return; } - final Keyboard keyboard = mView.getKeyboard(); - final Context context = mView.getContext(); - final KeyboardId keyboardId = keyboard.mId; + final KeyboardId keyboardId = mKeyboard.mId; final int elementId = keyboardId.mElementId; + final Context context = mView.getContext(); final int resId; switch (elementId) { @@ -388,12 +448,9 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp resId = R.string.spoken_description_mode_phone_shift; break; default: - resId = -1; - } - - if (resId < 0) { return; } + final String text = context.getString(resId); AccessibilityUtils.getInstance().announceForAccessibility(mView, text); } |