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

Commit c6245d13 authored by Jacky Kao's avatar Jacky Kao
Browse files

Uses SF callback windows for the A11yWindowInfo [2/n]

1. The SF callbacks the windows even they are in the transition state.
This will make many useless A11y events reporting to the A11y services,
like windows change with bounds change event. To avoid this symptom,
we assume the callback windows become stable and compute the reported
windows to the A11y framework if the SF callback isn't sent within 2
frames time (about 35ms).

2. To avoid the endless SF callback always in a short time, then A11y
framework can't obtain any windows, we set a maximum time, 500ms, which
is longer than the whole animation, to compute the reported windows.

3. Removes the legacy signals from the WM to compute the reported
windows due to they can be covered by the signals from the SF callback.

Bug: 191736824
Test: a11y CTS & unit tests
Test: Manual testing including the A11y services
Change-Id: I83e898d916b9a052bf4e1c265fdfc181cc31e232
parent d79253e1
Loading
Loading
Loading
Loading
+0 −10
Original line number Original line Diff line number Diff line
@@ -318,11 +318,6 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
        if (displayMagnifier != null) {
            displayMagnifier.onDisplaySizeChanged(displayContent);
            displayMagnifier.onDisplaySizeChanged(displayContent);
        }
        }
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindows();
        }
    }
    }


    void onAppWindowTransition(int displayId, int transition) {
    void onAppWindowTransition(int displayId, int transition) {
@@ -350,11 +345,6 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
        if (displayMagnifier != null) {
            displayMagnifier.onWindowTransition(windowState, transition);
            displayMagnifier.onWindowTransition(windowState, transition);
        }
        }
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindows();
        }
    }
    }


    void onWindowFocusChangedNot(int displayId) {
    void onWindowFocusChangedNot(int displayId) {
+60 −7
Original line number Original line Diff line number Diff line
@@ -48,6 +48,14 @@ import java.util.List;
public final class AccessibilityWindowsPopulator extends WindowInfosListener {
public final class AccessibilityWindowsPopulator extends WindowInfosListener {


    private static final String TAG = AccessibilityWindowsPopulator.class.getSimpleName();
    private static final String TAG = AccessibilityWindowsPopulator.class.getSimpleName();
    // If the surface flinger callback is not coming within in 2 frames time, i.e. about
    // 35ms, then assuming the windows become stable.
    private static final int SURFACE_FLINGER_CALLBACK_WINDOWS_STABLE_TIMES_MS = 35;
    // To avoid the surface flinger callbacks always comes within in 2 frames, then no windows
    // are reported to the A11y framework, and the animation duration time is 500ms, so setting
    // this value as the max timeout value to force computing changed windows.
    private static final int WINDOWS_CHANGED_NOTIFICATION_MAX_DURATION_TIMES_MS = 500;

    private static final float[] sTempFloats = new float[9];
    private static final float[] sTempFloats = new float[9];


    private final WindowManagerService mService;
    private final WindowManagerService mService;
@@ -114,6 +122,12 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
                }
                }
            }
            }
            if (mWindowsNotificationEnabled) {
            if (mWindowsNotificationEnabled) {
                if (!mHandler.hasMessages(
                        MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT)) {
                    mHandler.sendEmptyMessageDelayed(
                            MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT,
                            WINDOWS_CHANGED_NOTIFICATION_MAX_DURATION_TIMES_MS);
                }
                populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeededLocked();
                populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeededLocked();
            }
            }
        }
        }
@@ -165,11 +179,18 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            final int displayId = tempWindowHandleList.keyAt(i);
            final int displayId = tempWindowHandleList.keyAt(i);
            mInputWindowHandlesOnDisplays.put(displayId, tempWindowHandleList.get(displayId));
            mInputWindowHandlesOnDisplays.put(displayId, tempWindowHandleList.get(displayId));
        }
        }
        if (displayIdsForWindowsChanged.size() > 0

                && !mHandler.hasMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED)) {
        if (displayIdsForWindowsChanged.size() > 0) {
            if (!mHandler.hasMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED)) {
                mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED,
                mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED,
                        displayIdsForWindowsChanged).sendToTarget();
                        displayIdsForWindowsChanged).sendToTarget();
            }
            }

            return;
        }
        mHandler.removeMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE);
        mHandler.sendEmptyMessageDelayed(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE,
                SURFACE_FLINGER_CALLBACK_WINDOWS_STABLE_TIMES_MS);
    }
    }


    private void getDisplaysForWindowsChangedLocked(List<Integer> outDisplayIdsForWindowsChanged,
    private void getDisplaysForWindowsChangedLocked(List<Integer> outDisplayIdsForWindowsChanged,
@@ -238,22 +259,39 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
    }
    }


    private void notifyWindowsChanged(@NonNull List<Integer> displayIdsForWindowsChanged) {
    private void notifyWindowsChanged(@NonNull List<Integer> displayIdsForWindowsChanged) {
        mHandler.removeMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT);

        for (int i = 0; i < displayIdsForWindowsChanged.size(); i++) {
        for (int i = 0; i < displayIdsForWindowsChanged.size(); i++) {
            mAccessibilityController.performComputeChangedWindowsNot(
            mAccessibilityController.performComputeChangedWindowsNot(
                    displayIdsForWindowsChanged.get(i), false);
                    displayIdsForWindowsChanged.get(i), false);
        }
        }
    }
    }


    private void forceUpdateWindows() {
        final List<Integer> displayIdsForWindowsChanged = new ArrayList<>();

        synchronized (mLock) {
            for (int i = 0; i < mInputWindowHandlesOnDisplays.size(); i++) {
                final int displayId = mInputWindowHandlesOnDisplays.keyAt(i);
                displayIdsForWindowsChanged.add(displayId);
            }
        }
        notifyWindowsChanged(displayIdsForWindowsChanged);
    }

    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void releaseResources() {
    private void releaseResources() {
        mInputWindowHandlesOnDisplays.clear();
        mInputWindowHandlesOnDisplays.clear();
        mMagnificationSpecInverseMatrix.clear();
        mMagnificationSpecInverseMatrix.clear();
        mVisibleWindows.clear();
        mVisibleWindows.clear();
        mWindowsNotificationEnabled = false;
        mWindowsNotificationEnabled = false;
        mHandler.removeCallbacksAndMessages(null);
    }
    }


    private class MyHandler extends Handler {
    private class MyHandler extends Handler {
        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED = 1;
        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED = 1;
        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE = 2;
        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT = 3;


        MyHandler(Looper looper) {
        MyHandler(Looper looper) {
            super(looper, null, false);
            super(looper, null, false);
@@ -261,9 +299,24 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {


        @Override
        @Override
        public void handleMessage(Message message) {
        public void handleMessage(Message message) {
            if (message.what == MESSAGE_NOTIFY_WINDOWS_CHANGED) {
            switch (message.what) {
                case MESSAGE_NOTIFY_WINDOWS_CHANGED: {
                    final List<Integer> displayIdsForWindowsChanged = (List<Integer>) message.obj;
                    final List<Integer> displayIdsForWindowsChanged = (List<Integer>) message.obj;
                    notifyWindowsChanged(displayIdsForWindowsChanged);
                    notifyWindowsChanged(displayIdsForWindowsChanged);
                } break;

                case MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE: {
                    forceUpdateWindows();
                } break;

                case MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT: {
                    Slog.w(TAG, "Windows change within in 2 frames continuously over 500 ms "
                            + "and notify windows changed immediately");
                    mHandler.removeMessages(
                            MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE);

                    forceUpdateWindows();
                } break;
            }
            }
        }
        }
    }
    }
+0 −4
Original line number Original line Diff line number Diff line
@@ -197,9 +197,5 @@ public class ShellRoot {
                mAccessibilityWindow = null;
                mAccessibilityWindow = null;
            }
            }
        }
        }
        if (mDisplayContent.mWmService.mAccessibilityController.hasCallbacks()) {
            mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(
                    mDisplayContent.getDisplayId());
        }
    }
    }
}
}
+0 −3
Original line number Original line Diff line number Diff line
@@ -4807,9 +4807,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        if (isAnimating()) {
        if (isAnimating()) {
            return;
            return;
        }
        }
        if (mWmService.mAccessibilityController.hasCallbacks()) {
            mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId());
        }


        if (!isSelfOrAncestorWindowAnimatingExit()) {
        if (!isSelfOrAncestorWindowAnimatingExit()) {
            return;
            return;