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

Commit 14893878 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: Ibe2096e388769a12e3bcbaa472239ec9e458a396
parent a2fae6b5
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -318,11 +318,6 @@ final class AccessibilityController {
        if (displayMagnifier != null) {
            displayMagnifier.onDisplaySizeChanged(displayContent);
        }
        final WindowsForAccessibilityObserver windowsForA11yObserver =
                mWindowsForAccessibilityObserver.get(displayId);
        if (windowsForA11yObserver != null) {
            windowsForA11yObserver.scheduleComputeChangedWindows();
        }
    }

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

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

    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 final WindowManagerService mService;
@@ -114,6 +122,12 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
                }
            }
            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();
            }
        }
@@ -165,11 +179,18 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
            final int displayId = tempWindowHandleList.keyAt(i);
            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,
                        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,
@@ -239,22 +260,39 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
    }

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

        for (int i = 0; i < displayIdsForWindowsChanged.size(); i++) {
            mAccessibilityController.performComputeChangedWindowsNot(
                    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")
    private void releaseResources() {
        mInputWindowHandlesOnDisplays.clear();
        mMagnificationSpecInverseMatrix.clear();
        mVisibleWindows.clear();
        mWindowsNotificationEnabled = false;
        mHandler.removeCallbacksAndMessages(null);
    }

    private class MyHandler extends Handler {
        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) {
            super(looper, null, false);
@@ -262,9 +300,24 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {

        @Override
        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;
                    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 Diff line number Diff line
@@ -196,9 +196,5 @@ public class ShellRoot {
                mAccessibilityWindow = null;
            }
        }
        if (mDisplayContent.mWmService.mAccessibilityController.hasCallbacks()) {
            mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(
                    mDisplayContent.getDisplayId());
        }
    }
}
+0 −3
Original line number Diff line number Diff line
@@ -4992,9 +4992,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        if (isAnimating()) {
            return;
        }
        if (mWmService.mAccessibilityController.hasCallbacks()) {
            mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId());
        }

        if (!isSelfOrAncestorWindowAnimatingExit()) {
            return;