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

Commit 7b1c680e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Populate display id in A11yWindowManager"

parents 20472f6c 58b04e99
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1332,6 +1332,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
     * Convenience method to obtain a {@link #TYPE_WINDOWS_CHANGED} event for a specific window and
     * change set.
     *
     * @param displayId The ID of the display from which the event comes from
     * @param windowId The ID of the window that changed
     * @param windowChangeTypes The changes to populate
     * @return An instance of a TYPE_WINDOWS_CHANGED, populated with the requested fields and with
@@ -1340,8 +1341,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
     * @hide
     */
    public static AccessibilityEvent obtainWindowsChangedEvent(
            int windowId, int windowChangeTypes) {
            int displayId, int windowId, int windowChangeTypes) {
        final AccessibilityEvent event = new AccessibilityEvent(TYPE_WINDOWS_CHANGED);
        event.setDisplayId(displayId);
        event.setWindowId(windowId);
        event.setWindowChanges(windowChangeTypes);
        event.setImportantForAccessibility(true);
+3 −2
Original line number Diff line number Diff line
@@ -957,10 +957,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            // current state of the windows as the window manager may be delaying
            // the computation for performance reasons.
            boolean shouldComputeWindows = false;
            int displayId = Display.INVALID_DISPLAY;
            int displayId = event.getDisplayId();
            synchronized (mLock) {
                final int windowId = event.getWindowId();
                if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) {
                if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID
                        && displayId == Display.INVALID_DISPLAY) {
                    displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked(
                            resolvedUserId, windowId);
                    event.setDisplayId(displayId);
+44 −24
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.server.accessibility;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED;

import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;

@@ -275,22 +274,23 @@ public class AccessibilityWindowManager {
         * Sets the active flag of the window according to given windowId, others set to inactive.
         *
         * @param windowId The windowId
         * @return {@code true} if the window is in this display, {@code false} otherwise.
         */
        void setActiveWindowLocked(int windowId) {
        boolean setActiveWindowLocked(int windowId) {
            boolean foundWindow = false;
            if (mWindows != null) {
                final int windowCount = mWindows.size();
                for (int i = 0; i < windowCount; i++) {
                    AccessibilityWindowInfo window = mWindows.get(i);
                    if (window.getId() == windowId) {
                        window.setActive(true);
                        mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(
                                AccessibilityEvent.obtainWindowsChangedEvent(windowId,
                                        AccessibilityEvent.WINDOWS_CHANGE_ACTIVE));
                        foundWindow = true;
                    } else {
                        window.setActive(false);
                    }
                }
            }
            return foundWindow;
        }

        /**
@@ -298,24 +298,23 @@ public class AccessibilityWindowManager {
         * unfocused.
         *
         * @param windowId The windowId
         * @return {@code true} if the window is in this display, {@code false} otherwise.
         */
        void setAccessibilityFocusedWindowLocked(int windowId) {
        boolean setAccessibilityFocusedWindowLocked(int windowId) {
            boolean foundWindow = false;
            if (mWindows != null) {
                final int windowCount = mWindows.size();
                for (int i = 0; i < windowCount; i++) {
                    AccessibilityWindowInfo window = mWindows.get(i);
                    if (window.getId() == windowId) {
                        mAccessibilityFocusedDisplayId = mDisplayId;
                        window.setAccessibilityFocused(true);
                        mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(
                                AccessibilityEvent.obtainWindowsChangedEvent(
                                        windowId, WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED));

                        foundWindow = true;
                    } else {
                        window.setAccessibilityFocused(false);
                    }
                }
            }
            return foundWindow;
        }

        /**
@@ -704,7 +703,7 @@ public class AccessibilityWindowManager {
                final AccessibilityWindowInfo window = oldWindows.get(i);
                if (mA11yWindowInfoById.get(window.getId()) == null) {
                    events.add(AccessibilityEvent.obtainWindowsChangedEvent(
                            window.getId(), AccessibilityEvent.WINDOWS_CHANGE_REMOVED));
                            mDisplayId, window.getId(), AccessibilityEvent.WINDOWS_CHANGE_REMOVED));
                }
            }

@@ -714,13 +713,13 @@ public class AccessibilityWindowManager {
                final AccessibilityWindowInfo newWindow = mWindows.get(i);
                final AccessibilityWindowInfo oldWindow = oldWindowsById.get(newWindow.getId());
                if (oldWindow == null) {
                    events.add(AccessibilityEvent.obtainWindowsChangedEvent(
                    events.add(AccessibilityEvent.obtainWindowsChangedEvent(mDisplayId,
                            newWindow.getId(), AccessibilityEvent.WINDOWS_CHANGE_ADDED));
                } else {
                    int changes = newWindow.differenceFrom(oldWindow);
                    if (changes !=  0) {
                        events.add(AccessibilityEvent.obtainWindowsChangedEvent(
                                newWindow.getId(), changes));
                                mDisplayId, newWindow.getId(), changes));
                    }
                }
            }
@@ -1522,37 +1521,58 @@ public class AccessibilityWindowManager {

    private void setActiveWindowLocked(int windowId) {
        if (mActiveWindowId != windowId) {
            mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(
                    AccessibilityEvent.obtainWindowsChangedEvent(
            List<AccessibilityEvent> events = new ArrayList<>(2);
            if (mActiveWindowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) {
                final DisplayWindowsObserver observer =
                        getDisplayWindowObserverByWindowIdLocked(mActiveWindowId);
                if (observer != null) {
                    events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId,
                            mActiveWindowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE));
                }
            }

            mActiveWindowId = windowId;
            // Goes through all windows for each display.
            final int count = mDisplayWindowsObservers.size();
            for (int i = 0; i < count; i++) {
                final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i);
                if (observer != null) {
                    observer.setActiveWindowLocked(windowId);
                if (observer != null && observer.setActiveWindowLocked(windowId)) {
                    events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId,
                            windowId, AccessibilityEvent.WINDOWS_CHANGE_ACTIVE));
                }
            }

            for (final AccessibilityEvent event : events) {
                mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(event);
            }
        }
    }

    private void setAccessibilityFocusedWindowLocked(int windowId) {
        if (mAccessibilityFocusedWindowId != windowId) {
            mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(
                    AccessibilityEvent.obtainWindowsChangedEvent(
                            mAccessibilityFocusedWindowId,
                            WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED));
            List<AccessibilityEvent> events = new ArrayList<>(2);
            if (mAccessibilityFocusedDisplayId != Display.INVALID_DISPLAY
                    && mAccessibilityFocusedWindowId
                    != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) {
                events.add(AccessibilityEvent.obtainWindowsChangedEvent(
                        mAccessibilityFocusedDisplayId, mAccessibilityFocusedWindowId,
                        AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED));
            }

            mAccessibilityFocusedWindowId = windowId;
            // Goes through all windows for each display.
            final int count = mDisplayWindowsObservers.size();
            for (int i = 0; i < count; i++) {
                final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i);
                if (observer != null) {
                    observer.setAccessibilityFocusedWindowLocked(windowId);
                if (observer != null && observer.setAccessibilityFocusedWindowLocked(windowId)) {
                    mAccessibilityFocusedDisplayId = observer.mDisplayId;
                    events.add(AccessibilityEvent.obtainWindowsChangedEvent(observer.mDisplayId,
                            windowId, AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED));
                }
            }

            for (final AccessibilityEvent event : events) {
                mAccessibilityEventSender.sendAccessibilityEventForCurrentUserLocked(event);
            }
        }
    }
+157 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.accessibility;

import static com.android.server.accessibility.AccessibilityWindowManagerTest.DisplayIdMatcher.displayId;
import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowChangesMatcher.a11yWindowChanges;
import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.a11yWindowId;

@@ -587,10 +588,12 @@ public class AccessibilityWindowManagerTest {
        verify(mMockA11yEventSender, times(2))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(a11yWindowId(currentActiveWindowId),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(currentActiveWindowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
        assertThat(captor.getAllValues().get(1),
                allOf(a11yWindowId(eventWindowId),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(eventWindowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
    }

@@ -600,9 +603,58 @@ public class AccessibilityWindowManagerTest {
                DEFAULT_FOCUSED_INDEX);
        final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
        assertThat(currentA11yFocusedWindowId, is(not(eventWindowId)));
        assertThat(currentA11yFocusedWindowId, is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));

        final int noUse = 0;
        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
                eventWindowId,
                AccessibilityNodeInfo.ROOT_NODE_ID,
                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
                noUse);
        assertThat(mA11yWindowManager.getFocusedWindowId(
                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
        final ArgumentCaptor<AccessibilityEvent> captor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);
        verify(mMockA11yEventSender, times(1))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(eventWindowId),
                        a11yWindowChanges(
                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
    }

    @Test
    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_defaultToSecondary()
            throws RemoteException {
        runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
                Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID);
    }

    @Test
    public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_SecondaryToDefault()
            throws RemoteException {
        runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
                SECONDARY_DISPLAY_ID, Display.DEFAULT_DISPLAY);
    }

    private void runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
            int initialDisplayId, int eventDisplayId) throws RemoteException {
        startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
        final int initialWindowId = getWindowIdFromWindowInfosForDisplay(
                initialDisplayId, DEFAULT_FOCUSED_INDEX);
        final int noUse = 0;
        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
                initialWindowId,
                AccessibilityNodeInfo.ROOT_NODE_ID,
                AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
                noUse);
        assertThat(mA11yWindowManager.getFocusedWindowId(
                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(initialWindowId));
        Mockito.reset(mMockA11yEventSender);

        final int eventWindowId = getWindowIdFromWindowInfosForDisplay(
                eventDisplayId, DEFAULT_FOCUSED_INDEX);
        mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
                eventWindowId,
                AccessibilityNodeInfo.ROOT_NODE_ID,
@@ -615,11 +667,13 @@ public class AccessibilityWindowManagerTest {
        verify(mMockA11yEventSender, times(2))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(a11yWindowId(currentA11yFocusedWindowId),
                allOf(displayId(initialDisplayId),
                        a11yWindowId(initialWindowId),
                        a11yWindowChanges(
                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
        assertThat(captor.getAllValues().get(1),
                allOf(a11yWindowId(eventWindowId),
                allOf(displayId(eventDisplayId),
                        a11yWindowId(eventWindowId),
                        a11yWindowChanges(
                                AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
    }
@@ -674,10 +728,12 @@ public class AccessibilityWindowManagerTest {
        verify(mMockA11yEventSender, times(2))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(a11yWindowId(eventWindowId),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(eventWindowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
        assertThat(captor.getAllValues().get(1),
                allOf(a11yWindowId(currentActiveWindowId),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(currentActiveWindowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
    }

@@ -861,6 +917,77 @@ public class AccessibilityWindowManagerTest {
        assertTrue(TextUtils.equals(layoutParams.accessibilityTitle, a11yWindow.getTitle()));
    }

    @Test
    public void sendAccessibilityEventOnWindowRemoval() {
        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);

        // Removing index 0 because it's not focused, and avoids unnecessary layer change.
        final int windowId =
                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
        infos.remove(0);
        for (WindowInfo info : infos) {
            // Adjust layer number because it should start from 0.
            info.layer--;
        }

        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);

        final ArgumentCaptor<AccessibilityEvent> captor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);
        verify(mMockA11yEventSender, times(1))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(windowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
    }

    @Test
    public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);

        for (WindowInfo info : infos) {
            // Adjust layer number because new window will have 0 so that layer number in
            // A11yWindowInfo in window won't be changed.
            info.layer++;
        }

        final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
                false, USER_SYSTEM_ID);
        addWindowInfo(infos, token, 0);
        final int windowId =
                getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, infos.size() - 1);

        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);

        final ArgumentCaptor<AccessibilityEvent> captor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);
        verify(mMockA11yEventSender, times(1))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(windowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
    }

    @Test
    public void sendAccessibilityEventOnWindowChange() {
        final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
        infos.get(0).title = "new title";
        final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);

        onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);

        final ArgumentCaptor<AccessibilityEvent> captor =
                ArgumentCaptor.forClass(AccessibilityEvent.class);
        verify(mMockA11yEventSender, times(1))
                .sendAccessibilityEventForCurrentUserLocked(captor.capture());
        assertThat(captor.getAllValues().get(0),
                allOf(displayId(Display.DEFAULT_DISPLAY),
                        a11yWindowId(windowId),
                        a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
    }

    private void registerLeashedTokenAndWindowId() {
        mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID);
        mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID);
@@ -1018,6 +1145,29 @@ public class AccessibilityWindowManagerTest {
        }
    }

    static class DisplayIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
        private final int mDisplayId;

        DisplayIdMatcher(int displayId) {
            super();
            mDisplayId = displayId;
        }

        static DisplayIdMatcher displayId(int displayId) {
            return new DisplayIdMatcher(displayId);
        }

        @Override
        protected boolean matchesSafely(AccessibilityEvent event) {
            return event.getDisplayId() == mDisplayId;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("Matching to displayId " + mDisplayId);
        }
    }

    static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
        private int mWindowId;