From 92892608228f680aa7e7c24c79c6285adbf4f4c1 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 21 Apr 2014 19:26:08 -0700 Subject: [PATCH] Use sorted keys index as virtual view id Change-Id: Id3f81de1edaacc06362b65aa7b68e9317e6596bd --- .../AccessibilityEntityProvider.java | 100 +++++++++--------- .../AccessibleKeyboardViewProxy.java | 37 ++++--- .../keyboard/MainKeyboardView.java | 2 +- 3 files changed, 73 insertions(+), 66 deletions(-) diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java index 063f2113d..fc3b48c89 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java @@ -26,7 +26,6 @@ import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat; import android.support.v4.view.accessibility.AccessibilityRecordCompat; import android.util.Log; -import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; @@ -37,9 +36,10 @@ import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardView; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.SettingsValues; -import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; +import java.util.List; + /** * Exposes a virtual view sub-tree for {@link KeyboardView} and generates * {@link AccessibilityEvent}s for individual {@link Key}s. @@ -58,9 +58,6 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider private final KeyCodeDescriptionMapper mKeyCodeDescriptionMapper; private final AccessibilityUtils mAccessibilityUtils; - /** A map of integer IDs to {@link Key}s. */ - private final SparseArray mVirtualViewIdToKey = CollectionUtils.newSparseArray(); - /** Temporary rect used to calculate in-screen bounds. */ private final Rect mTempBoundsInScreen = new Rect(); @@ -73,6 +70,9 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider /** The current keyboard view. */ private KeyboardView mKeyboardView; + /** The current keyboard. */ + private Keyboard mKeyboard; + public AccessibilityEntityProvider(final KeyboardView keyboardView, final InputMethodService inputMethod) { mInputMethodService = inputMethod; @@ -92,14 +92,43 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider // Since this class is constructed lazily, we might not get a subsequent // call to setKeyboard() and therefore need to call it now. - setKeyboard(); + setKeyboard(keyboardView.getKeyboard()); } /** * Sets the keyboard represented by this node provider. + * + * @param keyboard The keyboard that is being set to the keyboard view. */ - public void setKeyboard() { - assignVirtualViewIds(); + public void setKeyboard(final Keyboard keyboard) { + mKeyboard = keyboard; + } + + private Key getKeyOf(final int virtualViewId) { + if (mKeyboard == null) { + return null; + } + final List sortedKeys = mKeyboard.getSortedKeys(); + // Use a virtual view id as an index of the sorted keys list. + if (virtualViewId >= 0 && virtualViewId < sortedKeys.size()) { + return sortedKeys.get(virtualViewId); + } + return null; + } + + private int getVirtualViewIdOf(final Key key) { + if (mKeyboard == null) { + return View.NO_ID; + } + final List sortedKeys = mKeyboard.getSortedKeys(); + final int size = sortedKeys.size(); + for (int index = 0; index < size; index++) { + if (sortedKeys.get(index) == key) { + // Use an index of the sorted keys list as a virtual view id. + return index; + } + } + return View.NO_ID; } /** @@ -112,7 +141,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider * @see AccessibilityEvent */ public AccessibilityEvent createAccessibilityEvent(final Key key, final int eventType) { - final int virtualViewId = generateVirtualViewIdForKey(key); + final int virtualViewId = getVirtualViewIdOf(key); final String keyDescription = getKeyDescription(key); final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); event.setPackageName(mKeyboardView.getContext().getPackageName()); @@ -158,16 +187,21 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView, rootInfo); // Add the virtual children of the root View. - final Keyboard keyboard = mKeyboardView.getKeyboard(); - for (final Key key : keyboard.getSortedKeys()) { - final int childVirtualViewId = generateVirtualViewIdForKey(key); - rootInfo.addChild(mKeyboardView, childVirtualViewId); + final List sortedKeys = mKeyboard.getSortedKeys(); + final int size = sortedKeys.size(); + for (int index = 0; index < size; index++) { + final Key key = sortedKeys.get(index); + if (key.isSpacer()) { + continue; + } + // Use an index of the sorted keys list as a virtual view id. + rootInfo.addChild(mKeyboardView, index); } return rootInfo; } - // Find the view that corresponds to the given id. - final Key key = mVirtualViewIdToKey.get(virtualViewId); + // Find the key that corresponds to the given virtual view id. + final Key key = getKeyOf(virtualViewId); if (key == null) { Log.e(TAG, "Invalid virtual view ID: " + virtualViewId); return null; @@ -226,7 +260,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider @Override public boolean performAction(final int virtualViewId, final int action, final Bundle arguments) { - final Key key = mVirtualViewIdToKey.get(virtualViewId); + final Key key = getKeyOf(virtualViewId); if (key == null) { return false; } @@ -242,7 +276,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider * @return The result of performing the action, or false if the action is not supported. */ boolean performActionForKey(final Key key, final int action, final Bundle arguments) { - final int virtualViewId = generateVirtualViewIdForKey(key); + final int virtualViewId = getVirtualViewIdOf(key); switch (action) { case AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS: @@ -288,7 +322,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo); final SettingsValues currentSettings = Settings.getInstance().getCurrent(); final String keyCodeDescription = mKeyCodeDescriptionMapper.getDescriptionForKey( - mKeyboardView.getContext(), mKeyboardView.getKeyboard(), key, shouldObscure); + mKeyboardView.getContext(), mKeyboard, key, shouldObscure); if (currentSettings.isWordSeparator(key.getCode())) { return mAccessibilityUtils.getAutoCorrectionDescription( keyCodeDescription, shouldObscure); @@ -297,40 +331,10 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider } } - /** - * Assigns virtual view IDs to keyboard keys and populates the related maps. - */ - private void assignVirtualViewIds() { - final Keyboard keyboard = mKeyboardView.getKeyboard(); - if (keyboard == null) { - return; - } - mVirtualViewIdToKey.clear(); - - for (final Key key : keyboard.getSortedKeys()) { - final int virtualViewId = generateVirtualViewIdForKey(key); - mVirtualViewIdToKey.put(virtualViewId, key); - } - } - /** * Updates the parent's on-screen location. */ private void updateParentLocation() { mKeyboardView.getLocationOnScreen(mParentLocation); } - - /** - * Generates a virtual view identifier for the given key. Returned - * identifiers are valid until the next global layout state change. - * - * @param key The key to identify. - * @return A virtual view identifier. - */ - private static int generateVirtualViewIdForKey(final Key key) { - // The key x- and y-coordinates are stable between layout changes. - // Generate an identifier by bit-shifting the x-coordinate to the - // left-half of the integer and OR'ing with the y-coordinate. - return ((0xFFFF & key.getX()) << (Integer.SIZE / 2)) | (0xFFFF & key.getY()); - } } diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index 0043b7844..c8fbb3d5a 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -55,6 +55,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp private InputMethodService mInputMethod; private MainKeyboardView mView; + private Keyboard mKeyboard; private AccessibilityEntityProvider mAccessibilityNodeProvider; private Key mLastHoverKey = null; @@ -66,6 +67,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp /** The most recently set keyboard mode. */ private int mLastKeyboardMode; + private static final int NOT_A_KEYBOARD_MODE = -1; public static void init(final InputMethodService inputMethod) { sInstance.initInternal(inputMethod); @@ -104,6 +106,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,15 +117,17 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp *

* Note: 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; } + mKeyboard = keyboard; if (mAccessibilityNodeProvider != null) { - mAccessibilityNodeProvider.setKeyboard(); + mAccessibilityNodeProvider.setKeyboard(keyboard); } - final int keyboardMode = mView.getKeyboard().mId.mMode; + final int keyboardMode = 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 @@ -139,7 +147,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp return; } announceKeyboardHidden(); - mLastKeyboardMode = -1; + mLastKeyboardMode = NOT_A_KEYBOARD_MODE; } /** @@ -148,7 +156,7 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp * * @param mode The new keyboard mode. */ - private void announceKeyboardMode(int mode) { + private void announceKeyboardMode(final int mode) { final int resId = KEYBOARD_MODE_RES_IDS.get(mode); if (resId == 0) { return; @@ -329,12 +337,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 +366,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 +394,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); } diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 1cafd4162..ecef8cc6c 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -406,7 +406,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack // This always needs to be set since the accessibility state can // potentially change without the keyboard being set again. - AccessibleKeyboardViewProxy.getInstance().setKeyboard(); + AccessibleKeyboardViewProxy.getInstance().setKeyboard(keyboard); } /**