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

Commit 3ff79da8 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Accessibility fix for ShellRoot"

parents fb966ede 90be6f3d
Loading
Loading
Loading
Loading
+59 −10
Original line number Diff line number Diff line
@@ -1587,6 +1587,52 @@ final class AccessibilityController {
            mCallback.onDisplayReparented(embeddedDisplayId);
        }

        boolean shellRootIsAbove(WindowState windowState, ShellRoot shellRoot) {
            int wsLayer = mService.mPolicy.getWindowLayerLw(windowState);
            int shellLayer = mService.mPolicy.getWindowLayerFromTypeLw(shellRoot.getWindowType(),
                    true);
            return shellLayer >= wsLayer;
        }

        int addShellRootsIfAbove(WindowState windowState, ArrayList<ShellRoot> shellRoots,
                int shellRootIndex, List<WindowInfo> windows, Set<IBinder> addedWindows,
                Region unaccountedSpace, boolean focusedWindowAdded) {
            while (shellRootIndex < shellRoots.size()
                    && shellRootIsAbove(windowState, shellRoots.get(shellRootIndex))) {
                ShellRoot shellRoot = shellRoots.get(shellRootIndex);
                shellRootIndex++;
                final WindowInfo info = shellRoot.getWindowInfo();
                if (info == null) {
                    continue;
                }

                info.layer = addedWindows.size();
                windows.add(info);
                addedWindows.add(info.token);
                unaccountedSpace.op(info.regionInScreen, unaccountedSpace,
                        Region.Op.REVERSE_DIFFERENCE);
                if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
                    break;
                }
            }
            return shellRootIndex;
        }

        private ArrayList<ShellRoot> getSortedShellRoots(
                SparseArray<ShellRoot> originalShellRoots) {
            ArrayList<ShellRoot> sortedShellRoots = new ArrayList<>(originalShellRoots.size());
            for (int i = originalShellRoots.size() - 1; i >= 0; --i) {
                sortedShellRoots.add(originalShellRoots.valueAt(i));
            }

            sortedShellRoots.sort((left, right) ->
                    mService.mPolicy.getWindowLayerFromTypeLw(right.getWindowType(), true)
                            - mService.mPolicy.getWindowLayerFromTypeLw(left.getWindowType(),
                            true));

            return sortedShellRoots;
        }

        /**
         * Check if windows have changed, and send them to the accessibility subsystem if they have.
         *
@@ -1646,9 +1692,22 @@ final class AccessibilityController {
                final int visibleWindowCount = visibleWindows.size();
                HashSet<Integer> skipRemainingWindowsForTasks = new HashSet<>();

                ArrayList<ShellRoot> shellRoots = getSortedShellRoots(dc.mShellRoots);

                // Iterate until we figure out what is touchable for the entire screen.
                int shellRootIndex = 0;
                for (int i = visibleWindowCount - 1; i >= 0; i--) {
                    final WindowState windowState = visibleWindows.valueAt(i);
                    int prevShellRootIndex = shellRootIndex;
                    shellRootIndex = addShellRootsIfAbove(windowState, shellRoots, shellRootIndex,
                            windows, addedWindows, unaccountedSpace, focusedWindowAdded);

                    // If a Shell Root was added, it could have accounted for all the space already.
                    if (shellRootIndex > prevShellRootIndex && unaccountedSpace.isEmpty()
                            && focusedWindowAdded) {
                        break;
                    }

                    final Region regionInScreen = new Region();
                    computeWindowRegionInScreen(windowState, regionInScreen);

@@ -1672,16 +1731,6 @@ final class AccessibilityController {
                    }
                }

                for (int i = dc.mShellRoots.size() - 1; i >= 0; --i) {
                    final WindowInfo info = dc.mShellRoots.valueAt(i).getWindowInfo();
                    if (info == null) {
                        continue;
                    }
                    info.layer = addedWindows.size();
                    windows.add(info);
                    addedWindows.add(info.token);
                }

                // Remove child/parent references to windows that were not added.
                final int windowCount = windows.size();
                for (int i = 0; i < windowCount; i++) {
+8 −4
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ public class ShellRoot {
    private SurfaceControl mSurfaceControl = null;
    private IWindow mAccessibilityWindow;
    private IBinder.DeathRecipient mAccessibilityWindowDeath;
    private int mWindowType;

    ShellRoot(@NonNull IWindow client, @NonNull DisplayContent dc,
            @WindowManager.ShellRootLayer final int shellRootLayer) {
@@ -64,19 +65,18 @@ public class ShellRoot {
            return;
        }
        mClient = client;
        int windowType;
        switch (shellRootLayer) {
            case SHELL_ROOT_LAYER_DIVIDER:
                windowType = TYPE_DOCK_DIVIDER;
                mWindowType = TYPE_DOCK_DIVIDER;
                break;
            case SHELL_ROOT_LAYER_PIP:
                windowType = TYPE_APPLICATION_OVERLAY;
                mWindowType = TYPE_APPLICATION_OVERLAY;
                break;
            default:
                throw new IllegalArgumentException(shellRootLayer
                        + " is not an acceptable shell root layer.");
        }
        mToken = new WindowToken.Builder(dc.mWmService, client.asBinder(), windowType)
        mToken = new WindowToken.Builder(dc.mWmService, client.asBinder(), mWindowType)
                .setDisplayContent(dc)
                .setPersistOnEmpty(true)
                .setOwnerCanManageAppTokens(true)
@@ -89,6 +89,10 @@ public class ShellRoot {
        mToken.getPendingTransaction().show(mSurfaceControl);
    }

    int getWindowType() {
        return mWindowType;
    }

    void clear() {
        if (mClient != null) {
            mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);