Loading core/java/android/app/ActivityView.java +38 −24 Original line number Diff line number Diff line Loading @@ -317,7 +317,7 @@ public class ActivityView extends ViewGroup { * regions and avoid focus switches by touches on this view. */ public void onLocationChanged() { updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); } @Override Loading @@ -329,37 +329,50 @@ public class ActivityView extends ViewGroup { public boolean gatherTransparentRegion(Region region) { // The tap exclude region may be affected by any view on top of it, so we detect the // possible change by monitoring this function. updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); return super.gatherTransparentRegion(region); } /** Compute and send current tap exclude region to WM for this view. */ private void updateTapExcludeRegion() { if (!isAttachedToWindow()) { /** * Sends current location in window and tap exclude region to WM for this view. */ private void updateLocationAndTapExcludeRegion() { if (mVirtualDisplay == null || !isAttachedToWindow()) { return; } try { int x = mLocationInWindow[0]; int y = mLocationInWindow[1]; getLocationInWindow(mLocationInWindow); if (x != mLocationInWindow[0] || y != mLocationInWindow[1]) { x = mLocationInWindow[0]; y = mLocationInWindow[1]; WindowManagerGlobal.getWindowSession().updateDisplayContentLocation( getWindow(), x, y, mVirtualDisplay.getDisplay().getDisplayId()); } updateTapExcludeRegion(x, y); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } } /** Computes and sends current tap exclude region to WM for this view. */ private void updateTapExcludeRegion(int x, int y) throws RemoteException { if (!canReceivePointerEvents()) { cleanTapExcludeRegion(); return; } try { getLocationInWindow(mLocationInWindow); final int x = mLocationInWindow[0]; final int y = mLocationInWindow[1]; mTapExcludeRegion.set(x, y, x + getWidth(), y + getHeight()); // There might be views on top of us. We need to subtract those areas from the tap // exclude region. final ViewParent parent = getParent(); if (parent instanceof ViewGroup) { ((ViewGroup) parent).subtractObscuredTouchableRegion(mTapExcludeRegion, this); if (parent != null) { parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this); } WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(), mTapExcludeRegion); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } } private class SurfaceCallback implements SurfaceHolder.Callback { Loading @@ -379,7 +392,7 @@ public class ActivityView extends ViewGroup { mVirtualDisplay.setDisplayState(true); } updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); } @Override Loading @@ -387,7 +400,7 @@ public class ActivityView extends ViewGroup { if (mVirtualDisplay != null) { mVirtualDisplay.resize(width, height, getBaseDisplayDensity()); } updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); } @Override Loading Loading @@ -471,7 +484,8 @@ public class ActivityView extends ViewGroup { try { // TODO: Find a way to consolidate these calls to the server. wm.reparentDisplayContent(displayId, mRootSurfaceControl); WindowManagerGlobal.getWindowSession().reparentDisplayContent( getWindow(), mRootSurfaceControl, displayId); wm.dontOverrideDisplayInfo(displayId); if (mSingleTaskInstance) { mActivityTaskManager.setDisplayToSingleTaskInstance(displayId); Loading core/java/android/view/IWindowManager.aidl +0 −12 Original line number Diff line number Diff line Loading @@ -621,18 +621,6 @@ interface IWindowManager */ void setShouldShowIme(int displayId, boolean shouldShow); /** * Reparent the top layers for a display to the requested surfaceControl. The display that * is going to be re-parented (the displayId passed in) needs to have been created by the same * process that is requesting the re-parent. This is to ensure clients can't just re-parent * display content info to any SurfaceControl, as this would be a security issue. * * @param displayId The id of the display. * @param surfaceControlHandle The SurfaceControl that the top level layers for the * display should be re-parented to. */ void reparentDisplayContent(int displayId, in SurfaceControl sc); /** * Waits for transactions to get applied before injecting input. * This includes waiting for the input windows to get sent to InputManager. Loading core/java/android/view/IWindowSession.aidl +25 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,31 @@ interface IWindowSession { void updatePointerIcon(IWindow window); /** * Reparent the top layers for a display to the requested SurfaceControl. The display that is * going to be re-parented (the displayId passed in) needs to have been created by the same * process that is requesting the re-parent. This is to ensure clients can't just re-parent * display content info to any SurfaceControl, as this would be a security issue. * * @param window The window which owns the SurfaceControl. This indicates the z-order of the * windows of this display against the windows on the parent display. * @param sc The SurfaceControl that the top level layers for the display should be re-parented * to. * @param displayId The id of the display to be re-parented. */ void reparentDisplayContent(IWindow window, in SurfaceControl sc, int displayId); /** * Update the location of a child display in its parent window. This enables windows in the * child display to compute the global transformation matrix. * * @param window The parent window of the display. * @param x The x coordinate in the parent window. * @param y The y coordinate in the parent window. * @param displayId The id of the display to be notified. */ void updateDisplayContentLocation(IWindow window, int x, int y, int displayId); /** * Update a tap exclude region identified by provided id in the window. Touches on this region * will neither be dispatched to this window nor change the focus to this window. Passing an Loading services/core/java/com/android/server/wm/AccessibilityController.java +23 −1 Original line number Diff line number Diff line Loading @@ -1108,6 +1108,7 @@ final class AccessibilityController { // the window manager is still looking for where to put it. // We will do the work when we get a focus change callback. // TODO(b/112273690): Support multiple displays // TODO(b/129098348): Support embedded displays if (mService.getDefaultDisplayContentLocked().mCurrentFocus == null) { return; } Loading Loading @@ -1401,6 +1402,27 @@ final class AccessibilityController { outWindows.put(mTempLayer++, w); } }, false /* traverseTopToBottom */); mService.mRoot.forAllWindows(w -> { final WindowState win = findRootDisplayParentWindow(w); if (win != null && win.getDisplayContent().isDefaultDisplay && w.isVisibleLw()) { // TODO(b/129098348): insert windows on child displays into outWindows based on // root-display-parent window. outWindows.put(mTempLayer++, w); } }, false /* traverseTopToBottom */); } private WindowState findRootDisplayParentWindow(WindowState win) { WindowState displayParentWindow = win.getDisplayContent().getParentWindow(); if (displayParentWindow == null) { return null; } WindowState candidate = displayParentWindow; while (candidate != null) { displayParentWindow = candidate; candidate = displayParentWindow.getDisplayContent().getParentWindow(); } return displayParentWindow; } private class MyHandler extends Handler { Loading services/core/java/com/android/server/wm/DisplayContent.java +45 −2 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; Loading Loading @@ -541,6 +542,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final InsetsStateController mInsetsStateController; /** @see #getParentWindow() */ private WindowState mParentWindow; private Point mLocationInParentWindow = new Point(); private SurfaceControl mParentSurfaceControl; private InputWindowHandle mPortalWindowHandle; Loading Loading @@ -4923,11 +4928,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** * Re-parent the DisplayContent's top surfaces, {@link #mWindowingLayer} and * {@link #mOverlayLayer} to the specified surfaceControl. * {@link #mOverlayLayer} to the specified SurfaceControl. * * @param win The window which owns the SurfaceControl. This indicates the z-order of the * windows of this display against the windows on the parent display. * @param sc The new SurfaceControl, where the DisplayContent's surfaces will be re-parented to. */ void reparentDisplayContent(SurfaceControl sc) { void reparentDisplayContent(WindowState win, SurfaceControl sc) { mParentWindow = win; mParentSurfaceControl = sc; if (mPortalWindowHandle == null) { mPortalWindowHandle = createPortalWindowHandle(sc.toString()); Loading @@ -4936,6 +4944,41 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo .reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc); } /** * Get the window which owns the surface that this DisplayContent is re-parented to. * * @return the parent window. */ WindowState getParentWindow() { return mParentWindow; } /** * Update the location of this display in the parent window. This enables windows in this * display to compute the global transformation matrix. * * @param win The parent window of this display. * @param x The x coordinate in the parent window. * @param y The y coordinate in the parent window. */ void updateLocation(WindowState win, int x, int y) { if (mParentWindow != win) { throw new IllegalArgumentException( "The given window is not the parent window of this display."); } if (mLocationInParentWindow.x != x || mLocationInParentWindow.y != y) { mLocationInParentWindow.x = x; mLocationInParentWindow.y = y; if (mWmService.mAccessibilityController != null) { mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(); } } } Point getLocationInParentWindow() { return mLocationInParentWindow; } @VisibleForTesting SurfaceControl getWindowingLayer() { return mWindowingLayer; Loading Loading
core/java/android/app/ActivityView.java +38 −24 Original line number Diff line number Diff line Loading @@ -317,7 +317,7 @@ public class ActivityView extends ViewGroup { * regions and avoid focus switches by touches on this view. */ public void onLocationChanged() { updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); } @Override Loading @@ -329,37 +329,50 @@ public class ActivityView extends ViewGroup { public boolean gatherTransparentRegion(Region region) { // The tap exclude region may be affected by any view on top of it, so we detect the // possible change by monitoring this function. updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); return super.gatherTransparentRegion(region); } /** Compute and send current tap exclude region to WM for this view. */ private void updateTapExcludeRegion() { if (!isAttachedToWindow()) { /** * Sends current location in window and tap exclude region to WM for this view. */ private void updateLocationAndTapExcludeRegion() { if (mVirtualDisplay == null || !isAttachedToWindow()) { return; } try { int x = mLocationInWindow[0]; int y = mLocationInWindow[1]; getLocationInWindow(mLocationInWindow); if (x != mLocationInWindow[0] || y != mLocationInWindow[1]) { x = mLocationInWindow[0]; y = mLocationInWindow[1]; WindowManagerGlobal.getWindowSession().updateDisplayContentLocation( getWindow(), x, y, mVirtualDisplay.getDisplay().getDisplayId()); } updateTapExcludeRegion(x, y); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } } /** Computes and sends current tap exclude region to WM for this view. */ private void updateTapExcludeRegion(int x, int y) throws RemoteException { if (!canReceivePointerEvents()) { cleanTapExcludeRegion(); return; } try { getLocationInWindow(mLocationInWindow); final int x = mLocationInWindow[0]; final int y = mLocationInWindow[1]; mTapExcludeRegion.set(x, y, x + getWidth(), y + getHeight()); // There might be views on top of us. We need to subtract those areas from the tap // exclude region. final ViewParent parent = getParent(); if (parent instanceof ViewGroup) { ((ViewGroup) parent).subtractObscuredTouchableRegion(mTapExcludeRegion, this); if (parent != null) { parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this); } WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(), mTapExcludeRegion); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } } private class SurfaceCallback implements SurfaceHolder.Callback { Loading @@ -379,7 +392,7 @@ public class ActivityView extends ViewGroup { mVirtualDisplay.setDisplayState(true); } updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); } @Override Loading @@ -387,7 +400,7 @@ public class ActivityView extends ViewGroup { if (mVirtualDisplay != null) { mVirtualDisplay.resize(width, height, getBaseDisplayDensity()); } updateTapExcludeRegion(); updateLocationAndTapExcludeRegion(); } @Override Loading Loading @@ -471,7 +484,8 @@ public class ActivityView extends ViewGroup { try { // TODO: Find a way to consolidate these calls to the server. wm.reparentDisplayContent(displayId, mRootSurfaceControl); WindowManagerGlobal.getWindowSession().reparentDisplayContent( getWindow(), mRootSurfaceControl, displayId); wm.dontOverrideDisplayInfo(displayId); if (mSingleTaskInstance) { mActivityTaskManager.setDisplayToSingleTaskInstance(displayId); Loading
core/java/android/view/IWindowManager.aidl +0 −12 Original line number Diff line number Diff line Loading @@ -621,18 +621,6 @@ interface IWindowManager */ void setShouldShowIme(int displayId, boolean shouldShow); /** * Reparent the top layers for a display to the requested surfaceControl. The display that * is going to be re-parented (the displayId passed in) needs to have been created by the same * process that is requesting the re-parent. This is to ensure clients can't just re-parent * display content info to any SurfaceControl, as this would be a security issue. * * @param displayId The id of the display. * @param surfaceControlHandle The SurfaceControl that the top level layers for the * display should be re-parented to. */ void reparentDisplayContent(int displayId, in SurfaceControl sc); /** * Waits for transactions to get applied before injecting input. * This includes waiting for the input windows to get sent to InputManager. Loading
core/java/android/view/IWindowSession.aidl +25 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,31 @@ interface IWindowSession { void updatePointerIcon(IWindow window); /** * Reparent the top layers for a display to the requested SurfaceControl. The display that is * going to be re-parented (the displayId passed in) needs to have been created by the same * process that is requesting the re-parent. This is to ensure clients can't just re-parent * display content info to any SurfaceControl, as this would be a security issue. * * @param window The window which owns the SurfaceControl. This indicates the z-order of the * windows of this display against the windows on the parent display. * @param sc The SurfaceControl that the top level layers for the display should be re-parented * to. * @param displayId The id of the display to be re-parented. */ void reparentDisplayContent(IWindow window, in SurfaceControl sc, int displayId); /** * Update the location of a child display in its parent window. This enables windows in the * child display to compute the global transformation matrix. * * @param window The parent window of the display. * @param x The x coordinate in the parent window. * @param y The y coordinate in the parent window. * @param displayId The id of the display to be notified. */ void updateDisplayContentLocation(IWindow window, int x, int y, int displayId); /** * Update a tap exclude region identified by provided id in the window. Touches on this region * will neither be dispatched to this window nor change the focus to this window. Passing an Loading
services/core/java/com/android/server/wm/AccessibilityController.java +23 −1 Original line number Diff line number Diff line Loading @@ -1108,6 +1108,7 @@ final class AccessibilityController { // the window manager is still looking for where to put it. // We will do the work when we get a focus change callback. // TODO(b/112273690): Support multiple displays // TODO(b/129098348): Support embedded displays if (mService.getDefaultDisplayContentLocked().mCurrentFocus == null) { return; } Loading Loading @@ -1401,6 +1402,27 @@ final class AccessibilityController { outWindows.put(mTempLayer++, w); } }, false /* traverseTopToBottom */); mService.mRoot.forAllWindows(w -> { final WindowState win = findRootDisplayParentWindow(w); if (win != null && win.getDisplayContent().isDefaultDisplay && w.isVisibleLw()) { // TODO(b/129098348): insert windows on child displays into outWindows based on // root-display-parent window. outWindows.put(mTempLayer++, w); } }, false /* traverseTopToBottom */); } private WindowState findRootDisplayParentWindow(WindowState win) { WindowState displayParentWindow = win.getDisplayContent().getParentWindow(); if (displayParentWindow == null) { return null; } WindowState candidate = displayParentWindow; while (candidate != null) { displayParentWindow = candidate; candidate = displayParentWindow.getDisplayContent().getParentWindow(); } return displayParentWindow; } private class MyHandler extends Handler { Loading
services/core/java/com/android/server/wm/DisplayContent.java +45 −2 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; Loading Loading @@ -541,6 +542,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final InsetsStateController mInsetsStateController; /** @see #getParentWindow() */ private WindowState mParentWindow; private Point mLocationInParentWindow = new Point(); private SurfaceControl mParentSurfaceControl; private InputWindowHandle mPortalWindowHandle; Loading Loading @@ -4923,11 +4928,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** * Re-parent the DisplayContent's top surfaces, {@link #mWindowingLayer} and * {@link #mOverlayLayer} to the specified surfaceControl. * {@link #mOverlayLayer} to the specified SurfaceControl. * * @param win The window which owns the SurfaceControl. This indicates the z-order of the * windows of this display against the windows on the parent display. * @param sc The new SurfaceControl, where the DisplayContent's surfaces will be re-parented to. */ void reparentDisplayContent(SurfaceControl sc) { void reparentDisplayContent(WindowState win, SurfaceControl sc) { mParentWindow = win; mParentSurfaceControl = sc; if (mPortalWindowHandle == null) { mPortalWindowHandle = createPortalWindowHandle(sc.toString()); Loading @@ -4936,6 +4944,41 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo .reparent(mWindowingLayer, sc).reparent(mOverlayLayer, sc); } /** * Get the window which owns the surface that this DisplayContent is re-parented to. * * @return the parent window. */ WindowState getParentWindow() { return mParentWindow; } /** * Update the location of this display in the parent window. This enables windows in this * display to compute the global transformation matrix. * * @param win The parent window of this display. * @param x The x coordinate in the parent window. * @param y The y coordinate in the parent window. */ void updateLocation(WindowState win, int x, int y) { if (mParentWindow != win) { throw new IllegalArgumentException( "The given window is not the parent window of this display."); } if (mLocationInParentWindow.x != x || mLocationInParentWindow.y != y) { mLocationInParentWindow.x = x; mLocationInParentWindow.y = y; if (mWmService.mAccessibilityController != null) { mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(); } } } Point getLocationInParentWindow() { return mLocationInParentWindow; } @VisibleForTesting SurfaceControl getWindowingLayer() { return mWindowingLayer; Loading