Accessibility fix for ShellRoot
Ensure ShellRoot layers are ordered correctly with other windows in the system. This means placing the Shell Root layers z ordered based on the window type Bug: 177864415 Test: adb shell dumpsys accessibility Change-Id: Iee982e9f17b496d413d4733f0a99997f81cee527 Merged-In: Iee982e9f17b496d413d4733f0a99997f81cee527
This commit is contained in:
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user