Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 616b84c9 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Use sorted keys index as virtual view id"

parents 3b798475 92892608
Loading
Loading
Loading
Loading
+52 −48
Original line number Diff line number Diff line
@@ -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<Key> 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<Key> 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<Key> 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<Key> 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());
    }
}
+20 −17
Original line number Diff line number Diff line
@@ -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
     * <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;
        }
        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);
    }
+1 −1
Original line number Diff line number Diff line
@@ -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);
    }

    /**