Use shellRoot to identify PIP menu window

Pip menu is an untouchable window which is exculded
from accessibility windows list. However it is touchable
when users touch in the pip mode window.

To fix it, we add this window to visible windows
list by comparing the window token.

Bug: 191736824
Test: a11y CTS & unit tests
Change-Id: I3d30d93bb92db467f37b7e659e2baea1a69cab16
This commit is contained in:
ryanlwlin
2021-11-22 11:36:07 +08:00
committed by Jacky Kao
parent 1489387870
commit 35433f3439
3 changed files with 30 additions and 49 deletions

View File

@@ -1645,10 +1645,11 @@ final class AccessibilityController {
// Ignore non-touchable windows, except the split-screen divider, which is
// occasionally non-touchable but still useful for identifying split-screen
// mode.
// mode and the PIP menu.
if (((a11yWindow.getFlags()
& WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
&& (a11yWindow.getType() != TYPE_DOCK_DIVIDER)) {
&& (a11yWindow.getType() != TYPE_DOCK_DIVIDER
&& !a11yWindow.isPIPMenu())) {
return false;
}

View File

@@ -26,6 +26,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Slog;
@@ -104,9 +105,14 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
inverseMatrix.set(mMagnificationSpecInverseMatrix.get(displayId));
}
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
final ShellRoot shellroot = dc.mShellRoots.get(WindowManager.SHELL_ROOT_LAYER_PIP);
final IBinder pipMenuIBinder =
shellroot != null ? shellroot.getAccessibilityWindowToken() : null;
for (final InputWindowHandle windowHandle : inputWindowHandles) {
final AccessibilityWindow accessibilityWindow =
AccessibilityWindow.initializeData(mService, windowHandle, inverseMatrix);
AccessibilityWindow.initializeData(mService, windowHandle, inverseMatrix,
pipMenuIBinder);
outWindows.add(accessibilityWindow);
}
@@ -335,6 +341,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
private int mFlags;
private int mType;
private int mPrivateFlags;
private boolean mIsPIPMenu;
private boolean mIsFocused;
private boolean mShouldMagnify;
private boolean mIgnoreDuetoRecentsAnimation;
@@ -351,7 +358,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
* @param inverseMatrix The magnification spec inverse matrix.
*/
public static AccessibilityWindow initializeData(WindowManagerService service,
InputWindowHandle inputWindowHandle, Matrix inverseMatrix) {
InputWindowHandle inputWindowHandle, Matrix inverseMatrix, IBinder pipIBinder) {
final IWindow window = inputWindowHandle.getWindow();
final WindowState windowState = window != null ? service.mWindowMap.get(
window.asBinder()) : null;
@@ -362,6 +369,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
instance.mDisplayId = inputWindowHandle.displayId;
instance.mFlags = inputWindowHandle.layoutParamsFlags;
instance.mType = inputWindowHandle.layoutParamsType;
instance.mIsPIPMenu = inputWindowHandle.getWindow().asBinder().equals(pipIBinder);
// TODO (b/199357848): gets the private flag of the window from other way.
instance.mPrivateFlags = windowState != null ? windowState.mAttrs.privateFlags : 0;
@@ -492,6 +500,13 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
return mTouchableRegionInScreen.isEmpty();
}
/**
* @return true if this window is PIP menu.
*/
public boolean isPIPMenu() {
return mIsPIPMenu;
}
private static void getTouchableRegionInWindow(boolean shouldMagnify, Region inRegion,
Region outRegion, Rect frame, Matrix inverseMatrix) {
// Some modal windows, like the activity with Theme.dialog, has the full screen
@@ -548,10 +563,9 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
// one is PIP.
if (windowInfo.type == TYPE_DOCK_DIVIDER) {
windowInfo.title = "Splitscreen Divider";
} else {
} else if (window.mIsPIPMenu) {
windowInfo.title = "Picture-in-Picture menu";
}
return windowInfo;
}
@@ -566,18 +580,19 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
@Override
public String toString() {
String builder = "A11yWindow=[" + mWindow
String builder = "A11yWindow=[" + mWindow.asBinder()
+ ", displayId=" + mDisplayId
+ ", flag=0x" + Integer.toHexString(mFlags)
+ ", type=" + mType
+ ", privateFlag=0x" + Integer.toHexString(mPrivateFlags)
+ ", focused=" + mIsFocused
+ ", magnify=" + mShouldMagnify
+ ", mShouldMagnify=" + mShouldMagnify
+ ", ignoreDuetoRecentsAnimation=" + mIgnoreDuetoRecentsAnimation
+ ", mIsTrustedOverlay=" + mIsTrustedOverlay
+ ", regionInScreen=" + mTouchableRegionInScreen
+ ", touchableRegion=" + mTouchableRegionInWindow
+ ", letterBoxBounds=" + mLetterBoxBounds
+ ", isPIPMenu=" + mIsPIPMenu
+ ", windowInfo=" + mWindowInfo
+ "]";

View File

@@ -25,15 +25,14 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMAT
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.IWindow;
import android.view.SurfaceControl;
import android.view.WindowInfo;
import android.view.WindowManager;
import android.view.animation.Animation;
@@ -136,46 +135,12 @@ public class ShellRoot {
ANIMATION_TYPE_WINDOW_ANIMATION);
}
WindowInfo getWindowInfo() {
if (mShellRootLayer != SHELL_ROOT_LAYER_DIVIDER
&& mShellRootLayer != SHELL_ROOT_LAYER_PIP) {
return null;
@Nullable
IBinder getAccessibilityWindowToken() {
if (mAccessibilityWindow != null) {
return mAccessibilityWindow.asBinder();
}
if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER) {
return null;
}
if (mShellRootLayer == SHELL_ROOT_LAYER_PIP
&& mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask() == null) {
return null;
}
if (mAccessibilityWindow == null) {
return null;
}
WindowInfo windowInfo = WindowInfo.obtain();
windowInfo.displayId = mToken.getDisplayArea().getDisplayContent().mDisplayId;
windowInfo.type = mToken.windowType;
windowInfo.layer = mToken.getWindowLayerFromType();
windowInfo.token = mAccessibilityWindow.asBinder();
windowInfo.focused = false;
windowInfo.hasFlagWatchOutsideTouch = false;
final Rect regionRect = new Rect();
// DividerView
if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER) {
windowInfo.inPictureInPicture = false;
mDisplayContent.getDockedDividerController().getTouchRegion(regionRect);
windowInfo.regionInScreen.set(regionRect);
windowInfo.title = "Splitscreen Divider";
}
// PipMenuView
if (mShellRootLayer == SHELL_ROOT_LAYER_PIP) {
windowInfo.inPictureInPicture = true;
mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask().getBounds(regionRect);
windowInfo.regionInScreen.set(regionRect);
windowInfo.title = "Picture-in-Picture menu";
}
return windowInfo;
return null;
}
void setAccessibilityWindow(IWindow window) {