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

Commit 56b61987 authored by Minche Li's avatar Minche Li Committed by Android (Google) Code Review
Browse files

Merge "Support A11y overlay on multi-display"

parents 786640c6 5f435e70
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -644,6 +644,32 @@ public abstract class AccessibilityService extends Service {
        }
    }

    @Override
    public Context createDisplayContext(Display display) {
        final Context context = super.createDisplayContext(display);
        final int displayId = display.getDisplayId();
        setDefaultTokenInternal(context, displayId);
        return context;
    }

    private void setDefaultTokenInternal(Context context, int displayId) {
        final WindowManagerImpl wm = (WindowManagerImpl) context.getSystemService(WINDOW_SERVICE);
        final IAccessibilityServiceConnection connection =
                AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
        IBinder token = null;
        if (connection != null) {
            synchronized (mLock) {
                try {
                    token = connection.getOverlayWindowToken(displayId);
                } catch (RemoteException re) {
                    Log.w(LOG_TAG, "Failed to get window token", re);
                    re.rethrowFromSystemServer();
                }
            }
            wm.setDefaultToken(token);
        }
    }

    /**
     * Returns the magnification controller, which may be used to query and
     * modify the state of display magnification.
+2 −0
Original line number Diff line number Diff line
@@ -96,4 +96,6 @@ interface IAccessibilityServiceConnection {
    void sendGesture(int sequence, in ParceledListSlice gestureSteps);

    boolean isFingerprintGestureDetectionAvailable();

    IBinder getOverlayWindowToken(int displayid);
}
+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.accessibilityservice.IAccessibilityServiceConnection;
import android.content.pm.ParceledListSlice;
import android.graphics.Region;
import android.os.Bundle;
import android.os.IBinder;

import java.util.List;

@@ -134,4 +135,8 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon
    public boolean isFingerprintGestureDetectionAvailable() {
        return false;
    }

    public IBinder getOverlayWindowToken(int displayId) {
        return null;
    }
}
+57 −5
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.accessibility;

import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
@@ -37,6 +36,7 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -49,6 +49,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MagnificationSpec;
import android.view.View;
@@ -91,6 +92,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
    private final WindowManagerInternal mWindowManagerService;
    private final GlobalActionPerformer mGlobalActionPerformer;
    private final AccessibilityWindowManager mA11yWindowManager;
    private final DisplayManager mDisplayManager;
    private final PowerManager mPowerManager;

    // Handler for scheduling method invocations on the main thread.
@@ -149,7 +151,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
    // types as message types allowing us to remove messages per event type.
    public Handler mEventDispatchHandler;

    final IBinder mOverlayWindowToken = new Binder();
    final SparseArray<IBinder> mOverlayWindowTokens = new SparseArray();


    public interface SystemSupport {
@@ -222,6 +224,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
        mSystemSupport = systemSupport;
        mInvocationHandler = new InvocationHandler(mainHandler.getLooper());
        mA11yWindowManager = a11yWindowManager;
        mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mEventDispatchHandler = new Handler(mainHandler.getLooper()) {
            @Override
@@ -928,24 +931,73 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
    }

    public void onAdded() {
        final Display[] displays = mDisplayManager.getDisplays();
        for (int i = 0; i < displays.length; i++) {
            final int displayId = displays[i].getDisplayId();
            onDisplayAdded(displayId);
        }
    }

    /**
     * Called whenever a logical display has been added to the system. Add a window token for adding
     * an accessibility overlay.
     *
     * @param displayId The id of the logical display that was added.
     */
    public void onDisplayAdded(int displayId) {
        final long identity = Binder.clearCallingIdentity();
        try {
            mWindowManagerService.addWindowToken(mOverlayWindowToken,
                    TYPE_ACCESSIBILITY_OVERLAY, DEFAULT_DISPLAY);
            final IBinder overlayWindowToken = new Binder();
            mWindowManagerService.addWindowToken(overlayWindowToken, TYPE_ACCESSIBILITY_OVERLAY,
                    displayId);
            synchronized (mLock) {
                mOverlayWindowTokens.put(displayId, overlayWindowToken);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    public void onRemoved() {
        final Display[] displays = mDisplayManager.getDisplays();
        for (int i = 0; i < displays.length; i++) {
            final int displayId = displays[i].getDisplayId();
            onDisplayRemoved(displayId);
        }
    }

    /**
     * Called whenever a logical display has been removed from the system. Remove a window token for
     * removing an accessibility overlay.
     *
     * @param displayId The id of the logical display that was added.
     */
    public void onDisplayRemoved(int displayId) {
        final long identity = Binder.clearCallingIdentity();
        try {
            mWindowManagerService.removeWindowToken(mOverlayWindowToken, true, DEFAULT_DISPLAY);
            mWindowManagerService.removeWindowToken(mOverlayWindowTokens.get(displayId), true,
                    displayId);
            synchronized (mLock) {
                mOverlayWindowTokens.remove(displayId);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * Gets overlay window token by the display Id.
     *
     * @param displayId The id of the logical display that was added.
     * @return window token.
     */
    @Override
    public IBinder getOverlayWindowToken(int displayId) {
        synchronized (mLock) {
            return mOverlayWindowTokens.get(displayId);
        }
    }

    public void resetLocked() {
        mSystemSupport.getKeyEventDispatcher().flush(this);
        try {
+15 −0
Original line number Diff line number Diff line
@@ -2550,6 +2550,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                    mInputFilter.onDisplayChanged();
                }
                UserState userState = getCurrentUserStateLocked();
                if (displayId != Display.DEFAULT_DISPLAY) {
                    final List<AccessibilityServiceConnection> services = userState.mBoundServices;
                    for (int i = 0; i < services.size(); i++) {
                        AccessibilityServiceConnection boundClient = services.get(i);
                        boundClient.onDisplayAdded(displayId);
                    }
                }
                updateMagnificationLocked(userState);
            }
        }
@@ -2566,6 +2573,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
                if (mInputFilter != null) {
                    mInputFilter.onDisplayChanged();
                }
                UserState userState = getCurrentUserStateLocked();
                if (displayId != Display.DEFAULT_DISPLAY) {
                    final List<AccessibilityServiceConnection> services = userState.mBoundServices;
                    for (int i = 0; i < services.size(); i++) {
                        AccessibilityServiceConnection boundClient = services.get(i);
                        boundClient.onDisplayRemoved(displayId);
                    }
                }
            }
            if (mMagnificationController != null) {
                mMagnificationController.onDisplayRemoved(displayId);
Loading