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

Commit a52af2c0 authored by mincheli's avatar mincheli Committed by Minche Li
Browse files

Support A11y button on multi-display

New api for a11y service to specify display id and return
accessibilitybutton controller per display.

Bug: 120762691
Test: a11y CTS & unit tests
Change-Id: I859c3b1257da3c3ad32dc23601134f42e11a4d07
parent a6a28fd2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2825,6 +2825,7 @@ package android.accessibilityservice {
    method public final boolean dispatchGesture(@NonNull android.accessibilityservice.GestureDescription, @Nullable android.accessibilityservice.AccessibilityService.GestureResultCallback, @Nullable android.os.Handler);
    method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
    method @NonNull public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
    method @NonNull public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController(int);
    method @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) @NonNull public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
    method @NonNull public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
    method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
+39 −12
Original line number Diff line number Diff line
@@ -391,7 +391,8 @@ public abstract class AccessibilityService extends Service {
        void onPerformGestureResult(int sequence, boolean completedSuccessfully);
        void onFingerprintCapturingGesturesChanged(boolean active);
        void onFingerprintGesture(int gesture);
        void onAccessibilityButtonClicked();
        /** Accessbility button clicked callbacks for different displays */
        void onAccessibilityButtonClicked(int displayId);
        void onAccessibilityButtonAvailabilityChanged(boolean available);
    }

@@ -459,7 +460,8 @@ public abstract class AccessibilityService extends Service {
    private final SparseArray<MagnificationController> mMagnificationControllers =
            new SparseArray<>(0);
    private SoftKeyboardController mSoftKeyboardController;
    private AccessibilityButtonController mAccessibilityButtonController;
    private final SparseArray<AccessibilityButtonController> mAccessibilityButtonControllers =
            new SparseArray<>(0);

    private int mGestureStatusCallbackSequence;

@@ -1521,17 +1523,40 @@ public abstract class AccessibilityService extends Service {
     */
    @NonNull
    public final AccessibilityButtonController getAccessibilityButtonController() {
        return getAccessibilityButtonController(Display.DEFAULT_DISPLAY);
    }

    /**
     * Returns the controller of specified logical display for the accessibility button within the
     * system's navigation area. This instance may be used to query the accessibility button's
     * state and register listeners for interactions with and state changes for the accessibility
     * button when {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} is set.
     * <p>
     * <strong>Note:</strong> Not all devices are capable of displaying the accessibility button
     * within a navigation area, and as such, use of this class should be considered only as an
     * optional feature or shortcut on supported device implementations.
     * </p>
     *
     * @param displayId The logic display id, use {@link Display#DEFAULT_DISPLAY} for default
     *                  display.
     * @return the accessibility button controller for this {@link AccessibilityService}
     */
    @NonNull
    public final AccessibilityButtonController getAccessibilityButtonController(int displayId) {
        synchronized (mLock) {
            if (mAccessibilityButtonController == null) {
                mAccessibilityButtonController = new AccessibilityButtonController(
            AccessibilityButtonController controller = mAccessibilityButtonControllers.get(
                    displayId);
            if (controller == null) {
                controller = new AccessibilityButtonController(
                        AccessibilityInteractionClient.getInstance().getConnection(mConnectionId));
                mAccessibilityButtonControllers.put(displayId, controller);
            }
            return mAccessibilityButtonController;
            return controller;
        }
    }

    private void onAccessibilityButtonClicked() {
        getAccessibilityButtonController().dispatchAccessibilityButtonClicked();
    private void onAccessibilityButtonClicked(int displayId) {
        getAccessibilityButtonController(displayId).dispatchAccessibilityButtonClicked();
    }

    private void onAccessibilityButtonAvailabilityChanged(boolean available) {
@@ -1737,8 +1762,8 @@ public abstract class AccessibilityService extends Service {
            }

            @Override
            public void onAccessibilityButtonClicked() {
                AccessibilityService.this.onAccessibilityButtonClicked();
            public void onAccessibilityButtonClicked(int displayId) {
                AccessibilityService.this.onAccessibilityButtonClicked(displayId);
            }

            @Override
@@ -1852,8 +1877,10 @@ public abstract class AccessibilityService extends Service {
            mCaller.sendMessage(mCaller.obtainMessageI(DO_ON_FINGERPRINT_GESTURE, gesture));
        }

        public void onAccessibilityButtonClicked() {
            final Message message = mCaller.obtainMessage(DO_ACCESSIBILITY_BUTTON_CLICKED);
        /** Accessibility button clicked callbacks for different displays */
        public void onAccessibilityButtonClicked(int displayId) {
            final Message message = mCaller.obtainMessageI(DO_ACCESSIBILITY_BUTTON_CLICKED,
                    displayId);
            mCaller.sendMessage(message);
        }

@@ -1987,7 +2014,7 @@ public abstract class AccessibilityService extends Service {

                case (DO_ACCESSIBILITY_BUTTON_CLICKED): {
                    if (mConnectionId != AccessibilityInteractionClient.NO_ID) {
                        mCallback.onAccessibilityButtonClicked();
                        mCallback.onAccessibilityButtonClicked(message.arg1);
                    }
                } return;

+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ import android.view.KeyEvent;

    void onFingerprintGesture(int gesture);

    void onAccessibilityButtonClicked();
    void onAccessibilityButtonClicked(int displayId);

    void onAccessibilityButtonAvailabilityChanged(boolean available);
}
+1 −1
Original line number Diff line number Diff line
@@ -1289,7 +1289,7 @@ public final class UiAutomation {
                }

                @Override
                public void onAccessibilityButtonClicked() {
                public void onAccessibilityButtonClicked(int displayId) {
                    /* do nothing */
                }

+8 −7
Original line number Diff line number Diff line
@@ -1185,8 +1185,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
        mInvocationHandler.notifySoftKeyboardShowModeChangedLocked(showState);
    }

    public void notifyAccessibilityButtonClickedLocked() {
        mInvocationHandler.notifyAccessibilityButtonClickedLocked();
    public void notifyAccessibilityButtonClickedLocked(int displayId) {
        mInvocationHandler.notifyAccessibilityButtonClickedLocked(displayId);
    }

    public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
@@ -1225,11 +1225,11 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
        }
    }

    private void notifyAccessibilityButtonClickedInternal() {
    private void notifyAccessibilityButtonClickedInternal(int displayId) {
        final IAccessibilityServiceClient listener = getServiceInterfaceSafely();
        if (listener != null) {
            try {
                listener.onAccessibilityButtonClicked();
                listener.onAccessibilityButtonClicked(displayId);
            } catch (RemoteException re) {
                Slog.e(LOG_TAG, "Error sending accessibility button click to " + mService, re);
            }
@@ -1481,7 +1481,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
                } break;

                case MSG_ON_ACCESSIBILITY_BUTTON_CLICKED: {
                    notifyAccessibilityButtonClickedInternal();
                    final int displayId = (int) message.arg1;
                    notifyAccessibilityButtonClickedInternal(displayId);
                } break;

                case MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED: {
@@ -1543,8 +1544,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
            mIsSoftKeyboardCallbackEnabled = enabled;
        }

        public void notifyAccessibilityButtonClickedLocked() {
            final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_CLICKED);
        public void notifyAccessibilityButtonClickedLocked(int displayId) {
            final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_CLICKED, displayId, 0);
            msg.sendToTarget();
        }

Loading