summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java69
-rw-r--r--services/core/java/com/android/server/wm/ShellRoot.java12
2 files changed, 67 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index ac0665a37c0b..a24319f7a98c 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1542,6 +1542,52 @@ final class AccessibilityController {
mEmbeddedDisplayIdList.add(displayId);
}
+ 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.
*
@@ -1601,9 +1647,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);
@@ -1627,16 +1686,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++) {
diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java
index b56e76d91370..be6a5d2fe27b 100644
--- a/services/core/java/com/android/server/wm/ShellRoot.java
+++ b/services/core/java/com/android/server/wm/ShellRoot.java
@@ -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);