summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2025-02-11 20:52:12 -0800
committer Vishnu Nair <vishnun@google.com> 2025-03-11 15:22:27 -0700
commit29372d3fb1f5fba12fca43849ddc3d24acdbff16 (patch)
treec4183da0efdcce8f187d8df6c927a192c3f20e58
parentb08353eb9f89a03475eec68581d2d2627bcd235e (diff)
Update SCVH InputTransferToken when available
Use the SCVH sidechannel to update host InputTransferToken when the view that is attached to the SCVH itself becomes attached to a window. This will update the mapping in WMS and allow the input APIs to work as expected. This allows callers to add a window with a SCVH instead of waiting until the window is created. As a result of this change, we allow SCVH to be reparented from one window to another. This cl also relaxes the requiement of passing a host InputTransferToken. The caller can rely on the sidechannel to pass the correct token when the SCVH is attached to a SurfaceView. Bug: 392965431 Test: presubmit Flag: com.android.window.flags.update_host_input_transfer_token Change-Id: I6cdbadfd1dfe1cd54426bfdf11de783c189fc091
-rw-r--r--core/java/android/view/ISurfaceControlViewHost.aidl2
-rw-r--r--core/java/android/view/IWindowSession.aidl5
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java14
-rw-r--r--core/java/android/view/SurfaceView.java34
-rw-r--r--core/java/android/view/ViewRootImpl.java5
-rw-r--r--core/java/android/view/WindowlessWindowManager.java48
-rw-r--r--core/java/android/window/flags/window_surfaces.aconfig12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt2
-rw-r--r--services/core/java/com/android/server/wm/EmbeddedWindowController.java32
-rw-r--r--services/core/java/com/android/server/wm/Session.java22
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java9
14 files changed, 158 insertions, 45 deletions
diff --git a/core/java/android/view/ISurfaceControlViewHost.aidl b/core/java/android/view/ISurfaceControlViewHost.aidl
index fd4b329570d9..83aceb3f9a7d 100644
--- a/core/java/android/view/ISurfaceControlViewHost.aidl
+++ b/core/java/android/view/ISurfaceControlViewHost.aidl
@@ -21,6 +21,7 @@ import android.graphics.Rect;
import android.view.InsetsState;
import android.view.ISurfaceControlViewHostParent;
import android.window.ISurfaceSyncGroup;
+import android.window.InputTransferToken;
/**
* API from content embedder back to embedded content in SurfaceControlViewHost
@@ -32,6 +33,7 @@ interface ISurfaceControlViewHost {
* APIs that are blocking
*/
oneway void onConfigurationChanged(in Configuration newConfig);
+ oneway void onDispatchAttachedToWindow(in InputTransferToken token);
oneway void onDispatchDetachedFromWindow();
oneway void onInsetsChanged(in InsetsState state, in Rect insetFrame);
ISurfaceSyncGroup getSurfaceSyncGroup();
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 7d6d5a269b4c..fbcbaaad1bce 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -311,8 +311,9 @@ interface IWindowSession {
/**
* Update the flags on an input channel associated with a particular surface.
*/
- oneway void updateInputChannel(in IBinder channelToken, int displayId,
- in SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
+ oneway void updateInputChannel(in IBinder channelToken,
+ in @nullable InputTransferToken hostInputTransferToken,
+ int displayId, in SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
in Region region);
/**
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 04ec4d0d382d..ecbf1f65f810 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -79,6 +79,20 @@ public class SurfaceControlViewHost {
}
@Override
+ public void onDispatchAttachedToWindow(InputTransferToken hostInputTransferToken) {
+ boolean hostInputTransferTokenChanged =
+ !Objects.equals(hostInputTransferToken, mWm.mHostInputTransferToken);
+ if (!hostInputTransferTokenChanged) {
+ return;
+ }
+
+ mWm.setHostInputTransferToken(hostInputTransferToken);
+ if (mViewRoot != null && mViewRoot.mView != null) {
+ mWm.updateInputChannel(getWindowToken().asBinder());
+ }
+ }
+
+ @Override
public void onDispatchDetachedFromWindow() {
if (mViewRoot == null) {
return;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 4f6c730857a8..1b57b0045537 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,6 +16,7 @@
package android.view;
+
import static android.view.flags.Flags.FLAG_DEPRECATE_SURFACE_VIEW_Z_ORDER_APIS;
import static android.view.flags.Flags.FLAG_SURFACE_VIEW_GET_SURFACE_PACKAGE;
import static android.view.flags.Flags.FLAG_SURFACE_VIEW_SET_COMPOSITION_ORDER;
@@ -23,6 +24,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER;
import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER;
+import static android.view.flags.Flags.FLAG_SURFACE_VIEW_GET_SURFACE_PACKAGE;
+import static android.view.flags.Flags.FLAG_SURFACE_VIEW_SET_COMPOSITION_ORDER;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
@@ -59,6 +62,7 @@ import android.util.Log;
import android.view.SurfaceControl.Transaction;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.IAccessibilityEmbeddedConnection;
+import android.window.InputTransferToken;
import android.window.SurfaceSyncGroup;
import com.android.graphics.hwui.flags.Flags;
@@ -347,7 +351,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
sv.mSurfacePackage.getRemoteInterface().attachParentInterface(this);
mSurfaceView = sv;
} catch (RemoteException e) {
- Log.d(TAG, "Failed to attach parent interface to SCVH. Likely SCVH is alraedy "
+ Log.d(TAG, "Failed to attach parent interface to SCVH. Likely SCVH is already "
+ "dead.");
}
}
@@ -492,10 +496,37 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mTag = "SV[" + System.identityHashCode(this) + windowName + "]";
}
+ private void dispatchScvhAttachedToHost() {
+ final ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot == null) {
+ return;
+ }
+
+ IBinder inputToken = viewRoot.getInputToken();
+ if (inputToken == null) {
+ // We don't have an input channel so we can't transfer focus or active
+ // touch gestures to embedded.
+ return;
+ }
+
+ try {
+ mSurfacePackage
+ .getRemoteInterface()
+ .onDispatchAttachedToWindow(new InputTransferToken(inputToken));
+ } catch (RemoteException e) {
+ Log.d(TAG,
+ "Failed to onDispatchAttachedToWindow to SCVH. Likely SCVH is already "
+ + "dead.");
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setTag();
+ if (mSurfacePackage != null) {
+ dispatchScvhAttachedToHost();
+ }
getViewRootImpl().addSurfaceChangedCallback(this);
mWindowStopped = false;
mViewVisibility = getVisibility() == VISIBLE;
@@ -2189,6 +2220,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
applyTransactionOnVriDraw(transaction);
}
mSurfacePackage = p;
+ dispatchScvhAttachedToHost();
mSurfaceControlViewHostParent.attach(this);
if (isFocused()) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index da91e8d2d256..6e50afab4b92 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -37,8 +37,8 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
-import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
import static android.view.Surface.FRAME_RATE_COMPATIBILITY_AT_LEAST;
+import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_BOOST;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_CONFLICTED;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
@@ -2676,7 +2676,8 @@ public final class ViewRootImpl implements ViewParent,
mStopped = stopped;
final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer;
if (renderer != null) {
- if (DEBUG_DRAW) Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
+ if (DEBUG_DRAW)
+ Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
renderer.setStopped(mStopped);
}
if (!mStopped) {
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 0a86ff89c53c..9a55194885fe 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -89,7 +89,7 @@ public class WindowlessWindowManager implements IWindowSession {
protected final SurfaceControl mRootSurface;
private final Configuration mConfiguration;
private final IWindowSession mRealWm;
- final InputTransferToken mHostInputTransferToken;
+ InputTransferToken mHostInputTransferToken;
private final InputTransferToken mInputTransferToken = new InputTransferToken();
private InsetsState mInsetsState;
private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
@@ -128,9 +128,11 @@ public class WindowlessWindowManager implements IWindowSession {
return null;
}
- /**
- * Utility API.
- */
+ void setHostInputTransferToken(InputTransferToken token) {
+ mHostInputTransferToken = token;
+ }
+
+ /** Utility API. */
void setCompletionCallback(IBinder window, ResizeCompleteCallback callback) {
if (mResizeCompletionForWindow.get(window) != null) {
Log.w(TAG, "Unsupported overlapping resizes");
@@ -151,11 +153,25 @@ public class WindowlessWindowManager implements IWindowSession {
return;
}
state.mInputRegion = region != null ? new Region(region) : null;
+ updateInputChannel(window);
+ }
+ }
+
+ protected void updateInputChannel(IBinder window) {
+ State state;
+ synchronized (this) {
+ // Do everything while locked so that we synchronize with relayout. This should be a
+ // very infrequent operation.
+ state = mStateForWindow.get(window);
+ if (state == null) {
+ return;
+ }
if (state.mInputChannelToken != null) {
try {
- mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
- state.mSurfaceControl, state.mParams.flags, state.mParams.privateFlags,
- state.mParams.inputFeatures, state.mInputRegion);
+ mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken,
+ state.mDisplayId, state.mSurfaceControl, state.mParams.flags,
+ state.mParams.privateFlags, state.mParams.inputFeatures,
+ state.mInputRegion);
} catch (RemoteException e) {
Log.e(TAG, "Failed to update surface input channel: ", e);
}
@@ -174,9 +190,7 @@ public class WindowlessWindowManager implements IWindowSession {
}
}
- /**
- * IWindowSession implementation.
- */
+ /** IWindowSession implementation. */
@Override
public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, @InsetsType int requestedVisibleTypes,
@@ -437,14 +451,15 @@ public class WindowlessWindowManager implements IWindowSession {
if ((attrChanges & inputChangeMask) != 0 && state.mInputChannelToken != null) {
try {
if (mRealWm instanceof IWindowSession.Stub) {
- mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
+ mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken,
+ state.mDisplayId,
new SurfaceControl(sc, "WindowlessWindowManager.relayout"),
attrs.flags, attrs.privateFlags, attrs.inputFeatures,
state.mInputRegion);
} else {
- mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc,
- attrs.flags, attrs.privateFlags, attrs.inputFeatures,
- state.mInputRegion);
+ mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken,
+ state.mDisplayId, sc, attrs.flags, attrs.privateFlags,
+ attrs.inputFeatures, state.mInputRegion);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to update surface input channel: ", e);
@@ -623,8 +638,9 @@ public class WindowlessWindowManager implements IWindowSession {
}
@Override
- public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
- int flags, int privateFlags, int inputFeatures, Region region) {
+ public void updateInputChannel(IBinder channelToken, InputTransferToken hostInputToken,
+ int displayId, SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
+ Region region) {
}
@Override
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index d866b0e2f89e..756288bdf5bf 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -118,3 +118,15 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "update_host_input_transfer_token"
+ namespace: "window_surfaces"
+ description: "Update host InpuTransferToken on view attach"
+ is_fixed_read_only: true
+ is_exported: true
+ bug: "392965431"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
index 812cc0161aae..bcbe123eb5e6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
@@ -167,6 +167,7 @@ class LetterboxInputDetector(
windowSession.updateInputChannel(
inputChannel.token,
+ null /* hostInputTransferToken */,
displayId,
inputSurface,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 7a4a834e9dc2..c33daf14e1a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -23,12 +23,12 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERL
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP;
-import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEdgeResizePermitted;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEventFromTouchscreen;
@@ -332,6 +332,7 @@ class DragResizeInputListener implements AutoCloseable {
try {
mWindowSession.updateInputChannel(
mInputChannel.getToken(),
+ null /* hostInputToken */,
mDisplayId,
mDecorationSurface,
FLAG_NOT_FOCUSABLE,
@@ -373,6 +374,7 @@ class DragResizeInputListener implements AutoCloseable {
try {
mWindowSession.updateInputChannel(
mSinkInputChannel.getToken(),
+ null /* hostInputToken */,
mDisplayId,
mInputSinkSurface,
FLAG_NOT_FOCUSABLE,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
index fa95faee4b6e..9c45cd22db19 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
@@ -35,6 +35,7 @@ import java.util.function.Supplier
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -191,6 +192,7 @@ class LetterboxInputControllerTest : ShellTestCase() {
fun checkUpdateSessionRegion(times: Int = 1, displayId: Int = DISPLAY_ID, region: Region) {
verify(windowSession, times(times)).updateInputChannel(
any(),
+ anyOrNull(),
eq(displayId),
any(),
any(),
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 7b6fc9e5694d..64ae21dc69de 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -239,9 +239,10 @@ class EmbeddedWindowController {
static class EmbeddedWindow implements InputTarget {
final IBinder mClient;
- @Nullable final WindowState mHostWindowState;
+ @Nullable WindowState mHostWindowState;
@Nullable final ActivityRecord mHostActivityRecord;
- final String mName;
+ String mName;
+ final String mInputHandleName;
final int mOwnerUid;
final int mOwnerPid;
final WindowManagerService mWmService;
@@ -279,13 +280,12 @@ class EmbeddedWindowController {
* @param displayId used for focus requests
*/
EmbeddedWindow(Session session, WindowManagerService service, IBinder clientToken,
- WindowState hostWindowState, int ownerUid, int ownerPid, int windowType,
- int displayId, InputTransferToken inputTransferToken, String inputHandleName,
- boolean isFocusable) {
+ @Nullable WindowState hostWindowState, int ownerUid, int ownerPid,
+ int windowType, int displayId, InputTransferToken inputTransferToken,
+ String inputHandleName, boolean isFocusable) {
mSession = session;
mWmService = service;
mClient = clientToken;
- mHostWindowState = hostWindowState;
mHostActivityRecord = (mHostWindowState != null) ? mHostWindowState.mActivityRecord
: null;
mOwnerUid = ownerUid;
@@ -293,11 +293,9 @@ class EmbeddedWindowController {
mWindowType = windowType;
mDisplayId = displayId;
mInputTransferToken = inputTransferToken;
- final String hostWindowName =
- (mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString()
- : "";
mIsFocusable = isFocusable;
- mName = "Embedded{" + inputHandleName + hostWindowName + "}";
+ mInputHandleName = inputHandleName;
+ updateHost(hostWindowState);
}
@Override
@@ -486,5 +484,19 @@ class EmbeddedWindowController {
proto.end(token2);
proto.end(token);
}
+
+ public void updateHost(WindowState hostWindowState) {
+ if (mHostWindowState == hostWindowState && mName != null) {
+ return;
+ }
+
+ ProtoLog.d(WM_DEBUG_EMBEDDED_WINDOWS, "[%s] Updated host window from %s to %s",
+ this, mHostWindowState, hostWindowState);
+ mHostWindowState = hostWindowState;
+ final String hostWindowName =
+ (mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString()
+ : "";
+ mName = "Embedded{" + mInputHandleName + hostWindowName + "}";
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 3ed16db7e204..087362189ee2 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -910,10 +910,16 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
int privateFlags, int inputFeatures, int type, IBinder windowToken,
InputTransferToken inputTransferToken, String inputHandleName,
InputChannel outInputChannel) {
- if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) {
- // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
- // embedded windows without providing a host window input token
- throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ if (!Flags.updateHostInputTransferToken()) {
+ // This is not a valid security check, callers can pass in a bogus token. If the
+ // token is not known to wm, then input APIs is request focus or transferTouchGesture
+ // will fail. Removing this check allows SCVH to be created before associating with a
+ // host window.
+ if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) {
+ // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
+ // embedded windows without providing a host window input token
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
}
final long identity = Binder.clearCallingIdentity();
@@ -928,12 +934,14 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
@Override
- public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
+ public void updateInputChannel(IBinder channelToken,
+ @Nullable InputTransferToken hostInputTransferToken,
+ int displayId, SurfaceControl surface,
int flags, int privateFlags, int inputFeatures, Region region) {
final long identity = Binder.clearCallingIdentity();
try {
- mService.updateInputChannel(channelToken, displayId, surface, flags,
- mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region);
+ mService.updateInputChannel(channelToken, hostInputTransferToken, displayId, surface,
+ flags, mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c078d67b6cc6..76920033a782 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9322,10 +9322,12 @@ public class WindowManagerService extends IWindowManager.Stub
/**
* Updates the flags on an existing surface's input channel. This assumes the surface provided
- * is the one associated with the provided input-channel. If this isn't the case, behavior
- * is undefined.
+ * is the one associated with the provided input-channel. If this isn't the case, behavior is
+ * undefined.
*/
- void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
+ void updateInputChannel(IBinder channelToken,
+ @Nullable InputTransferToken hostInputTransferToken, int displayId,
+ SurfaceControl surface,
int flags, int privateFlags, int inputFeatures, Region region) {
final InputApplicationHandle applicationHandle;
final String name;
@@ -9339,6 +9341,11 @@ public class WindowManagerService extends IWindowManager.Stub
name = win.toString();
applicationHandle = win.getApplicationHandle();
win.setIsFocusable((flags & FLAG_NOT_FOCUSABLE) == 0);
+ if (Flags.updateHostInputTransferToken()) {
+ WindowState hostWindowState = hostInputTransferToken != null
+ ? mInputToWindowMap.get(hostInputTransferToken.getToken()) : null;
+ win.updateHost(hostWindowState);
+ }
}
updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 71e84c0f1821..73102c4478d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -1147,7 +1147,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
assertThrows(IllegalArgumentException.class, () ->
- mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+ mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */,
+ DEFAULT_DISPLAY, surfaceControl,
FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
null /* region */));
}
@@ -1217,7 +1218,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
eq(surfaceControl),
argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
- mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+ mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */,
+ DEFAULT_DISPLAY, surfaceControl,
FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
null /* region */);
verify(mTransaction).setInputWindowInfo(
@@ -1244,7 +1246,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
eq(surfaceControl),
argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_PRIVACY) == 0));
- mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+ mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */,
+ DEFAULT_DISPLAY, surfaceControl,
FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
INPUT_FEATURE_SENSITIVE_FOR_PRIVACY,
null /* region */);