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

Commit 0b423b70 authored by Jacky Kao's avatar Jacky Kao Committed by Android (Google) Code Review
Browse files

Merge "Supporting windows updated per display [Part I]"

parents a83f236b f93252b7
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -579,10 +579,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            // Make sure clients receiving this event will be able to get the
            // current state of the windows as the window manager may be delaying
            // the computation for performance reasons.
            // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
            if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
                    && mA11yWindowManager.isTrackingWindowsLocked()) {
                WindowManagerInternal wm = LocalServices.getService(WindowManagerInternal.class);
                wm.computeWindowsForAccessibility();
                wm.computeWindowsForAccessibility(Display.DEFAULT_DISPLAY);
            }
            synchronized (mLock) {
                notifyAccessibilityServicesDelayedLocked(event, false);
@@ -2616,8 +2617,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        public final RemoteCallbackList<IAccessibilityManagerClient> mUserClients =
                new RemoteCallbackList<>();

        public final SparseArray<IBinder> mWindowTokens = new SparseArray<>();

        // Transient state.

        public final ArrayList<AccessibilityServiceConnection> mBoundServices = new ArrayList<>();
+9 −3
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.IWindow;
import android.view.WindowInfo;
import android.view.WindowManager;
@@ -311,7 +312,9 @@ public class AccessibilityWindowManager
                // In some cases, onWindowsForAccessibilityChanged will be called immediately in
                // setWindowsForAccessibilityCallback. We'll lost windows if flag is false.
                mTrackingWindows = true;
                mWindowManagerInternal.setWindowsForAccessibilityCallback(this);
                // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
                mWindowManagerInternal.setWindowsForAccessibilityCallback(Display.DEFAULT_DISPLAY,
                        this);
            }
        }
    }
@@ -322,7 +325,9 @@ public class AccessibilityWindowManager
    public void stopTrackingWindows() {
        synchronized (mLock) {
            if (mTrackingWindows) {
                mWindowManagerInternal.setWindowsForAccessibilityCallback(null);
                // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
                mWindowManagerInternal.setWindowsForAccessibilityCallback(Display.DEFAULT_DISPLAY,
                        null);
                mTrackingWindows = false;
                clearWindowsLocked();
            }
@@ -521,7 +526,8 @@ public class AccessibilityWindowManager
                }
            }
        }
        mWindowManagerInternal.computeWindowsForAccessibility();
        // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
        mWindowManagerInternal.computeWindowsForAccessibility(Display.DEFAULT_DISPLAY);
        return windowId;
    }

+106 −37
Original line number Diff line number Diff line
@@ -85,7 +85,8 @@ final class AccessibilityController {

    private SparseArray<DisplayMagnifier> mDisplayMagnifiers = new SparseArray<>();

    private WindowsForAccessibilityObserver mWindowsForAccessibilityObserver;
    private SparseArray<WindowsForAccessibilityObserver> mWindowsForAccessibilityObserver =
            new SparseArray<>();

    public boolean setMagnificationCallbacksLocked(int displayId,
            MagnificationCallbacks callbacks) {
@@ -115,27 +116,52 @@ final class AccessibilityController {
        return result;
    }

    public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
    public boolean setWindowsForAccessibilityCallbackLocked(int displayId,
            WindowsForAccessibilityCallback callback) {
        if (callback != null) {
            if (mWindowsForAccessibilityObserver != null) {
            final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
            if (dc == null) {
                return false;
            }

            final Display display = dc.getDisplay();
            if (mWindowsForAccessibilityObserver.get(displayId) != null) {
                if (display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null) {
                    // The window observer of this embedded display had been set from
                    // window manager after setting its parent window
                    return true;
                } else {
                    throw new IllegalStateException(
                        "Windows for accessibility callback already set!");
                            "Windows for accessibility callback of display "
                                    + displayId + " already set!");
                }
            }
            mWindowsForAccessibilityObserver = new WindowsForAccessibilityObserver(
                    mService, callback);
            if (display.getType() == Display.TYPE_OVERLAY) {
                return false;
            }
            mWindowsForAccessibilityObserver.put(displayId,
                    new WindowsForAccessibilityObserver(mService, displayId, callback));
        } else {
            if (mWindowsForAccessibilityObserver == null) {
            final WindowsForAccessibilityObserver windowsForA11yObserver =
                    mWindowsForAccessibilityObserver.get(displayId);
            if  (windowsForA11yObserver == null) {
                throw new IllegalStateException(
                        "Windows for accessibility callback already cleared!");
                        "Windows for accessibility callback of display " + displayId
                                + " already cleared!");
            }
            mWindowsForAccessibilityObserver = null;
            mWindowsForAccessibilityObserver.remove(displayId);
        }
        return true;
    }

    public void performComputeChangedWindowsNotLocked(boolean forceSend) {
    public void performComputeChangedWindowsNotLocked(int displayId, boolean forceSend) {
        WindowsForAccessibilityObserver observer = null;
        synchronized (mService) {
            observer = mWindowsForAccessibilityObserver;
            final WindowsForAccessibilityObserver windowsForA11yObserver =
                    mWindowsForAccessibilityObserver.get(displayId);
            if (windowsForA11yObserver != null) {
                observer = windowsForA11yObserver;
            }
        }
        if (observer != null) {
            observer.performComputeChangedWindowsNotLocked(forceSend);
@@ -147,9 +173,10 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
            displayMagnifier.setMagnificationSpecLocked(spec);
        }
        // TODO: support multi-display for windows observer
        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
        }
    }

@@ -173,9 +200,10 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
            displayMagnifier.onWindowLayersChangedLocked();
        }
        // TODO: support multi-display for windows observer
        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
        }
    }

@@ -185,9 +213,10 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
            displayMagnifier.onRotationChangedLocked(displayContent);
        }
        // TODO: support multi-display for windows observer
        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
        }
    }

@@ -206,29 +235,36 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
            displayMagnifier.onWindowTransitionLocked(windowState, transition);
        }
        // TODO: support multi-display for windows observer
        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
        }
    }

    public void onWindowFocusChangedNotLocked() {
    public void onWindowFocusChangedNotLocked(int displayId) {
        // Not relevant for the display magnifier.

        WindowsForAccessibilityObserver observer = null;
        synchronized (mService) {
            observer = mWindowsForAccessibilityObserver;
            final WindowsForAccessibilityObserver windowsForA11yObserver =
                    mWindowsForAccessibilityObserver.get(displayId);
            if (windowsForA11yObserver != null) {
                observer = windowsForA11yObserver;
            }
        }
        if (observer != null) {
            observer.performComputeChangedWindowsNotLocked(false);
        }
    }

    public void onSomeWindowResizedOrMovedLocked() {
    public void onSomeWindowResizedOrMovedLocked(int displayId) {
        // Not relevant for the display magnifier.

        if (mWindowsForAccessibilityObserver != null) {
            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
        }
    }

@@ -264,6 +300,29 @@ final class AccessibilityController {
        }
    }

    public void handleWindowObserverOfEmbeddedDisplayLocked(int embeddedDisplayId,
            WindowState parentWindow) {
        if (embeddedDisplayId == Display.DEFAULT_DISPLAY || parentWindow == null) {
            return;
        }
        // Finds the parent display of this embedded display
        final int parentDisplayId;
        WindowState candidate = parentWindow;
        while (candidate != null) {
            parentWindow = candidate;
            candidate = parentWindow.getDisplayContent().getParentWindow();
        }
        parentDisplayId = parentWindow.getDisplayId();
        // Uses the observer of parent display
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(parentDisplayId);

        if (windowsForA11yObserver != null) {
            // Replaces the observer of embedded display to the one of parent display
            mWindowsForAccessibilityObserver.put(embeddedDisplayId, windowsForA11yObserver);
        }
    }

    private static void populateTransformationMatrixLocked(WindowState windowState,
            Matrix outMatrix) {
        windowState.getTransformationMatrix(sTempFloats, outMatrix);
@@ -1059,13 +1118,17 @@ final class AccessibilityController {

        private final WindowsForAccessibilityCallback mCallback;

        private final int mDisplayId;

        private final long mRecurringAccessibilityEventsIntervalMillis;

        public WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
                int displayId,
                WindowsForAccessibilityCallback callback) {
            mContext = windowManagerService.mContext;
            mService = windowManagerService;
            mCallback = callback;
            mDisplayId = displayId;
            mHandler = new MyHandler(mService.mH.getLooper());
            mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration
                    .getSendRecurringAccessibilityEventsInterval();
@@ -1100,14 +1163,17 @@ final class AccessibilityController {
                // Do not send the windows if there is no current focus as
                // the window manager is still looking for where to put it.
                // We will do the work when we get a focus change callback.
                // TODO(b/112273690): Support multiple displays
                // TODO [Multi-Display] : only checks top focused window
                if (!isCurrentFocusWindowOnDefaultDisplay()) {
                    return;
                }

                WindowManager windowManager = (WindowManager)
                        mContext.getSystemService(Context.WINDOW_SERVICE);
                windowManager.getDefaultDisplay().getRealSize(mTempPoint);
                final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
                if (dc == null) {
                    return;
                }
                final Display display = dc.getDisplay();
                display.getRealSize(mTempPoint);
                final int screenWidth = mTempPoint.x;
                final int screenHeight = mTempPoint.y;

@@ -1305,7 +1371,11 @@ final class AccessibilityController {

        private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
            final List<WindowState> tempWindowStatesList = new ArrayList<>();
            final DisplayContent dc = mService.getDefaultDisplayContentLocked();
            final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
            if (dc == null) {
                return;
            }

            dc.forAllWindows(w -> {
                if (w.isVisibleLw()) {
                    tempWindowStatesList.add(w);
@@ -1319,8 +1389,7 @@ final class AccessibilityController {
                    return;
                }

                if (w.isVisibleLw() && parentWindow.getDisplayContent().isDefaultDisplay
                        && tempWindowStatesList.contains(parentWindow)) {
                if (w.isVisibleLw() && tempWindowStatesList.contains(parentWindow)) {
                    tempWindowStatesList.add(tempWindowStatesList.lastIndexOf(parentWindow), w);
                }
            }, false /* traverseTopToBottom */);
@@ -1341,7 +1410,7 @@ final class AccessibilityController {
            }
            return displayParentWindow;
        }

        // TODO [Multi-Display] : only checks top focused window
        private boolean isCurrentFocusWindowOnDefaultDisplay() {
            final WindowState focusedWindow =
                    mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
+1 −1
Original line number Diff line number Diff line
@@ -5111,7 +5111,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (!mLocationInParentWindow.equals(x, y)) {
            mLocationInParentWindow.set(x, y);
            if (mWmService.mAccessibilityController != null) {
                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(mDisplayId);
            }
            notifyLocationInParentDisplayChanged();
        }
+8 −4
Original line number Diff line number Diff line
@@ -263,11 +263,13 @@ public abstract class WindowManagerInternal {

    /**
     * Sets a callback for observing which windows are touchable for the purposes
     * of accessibility.
     * of accessibility on specified display.
     *
     * @param displayId The logical display id.
     * @param callback The callback.
     * @return {@code false} if display id is not valid.
     */
    public abstract void setWindowsForAccessibilityCallback(
    public abstract boolean setWindowsForAccessibilityCallback(int displayId,
            WindowsForAccessibilityCallback callback);

    /**
@@ -418,9 +420,11 @@ public abstract class WindowManagerInternal {
    public abstract boolean isStackVisibleLw(int windowingMode);

    /**
     * Requests the window manager to resend the windows for accessibility.
     * Requests the window manager to resend the windows for accessibility on specified display.
     *
     * @param displayId Display ID to be computed its windows for accessibility
     */
    public abstract void computeWindowsForAccessibility();
    public abstract void computeWindowsForAccessibility(int displayId);

    /**
     * Called after virtual display Id is updated by
Loading