summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rob Carr <racarr@google.com> 2022-01-27 17:47:47 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-01-27 17:47:47 +0000
commit3752207242dd384daedb829a675f6a4335383fc8 (patch)
tree5bc0e928c448c2f0de09b7209387fc93396505c0
parentf214e0d92e03accf33d9ecfd5a62a17fa3f516a1 (diff)
parentb41528c5b3c24963e9608763d1bee8de18c07168 (diff)
Merge changes I22e22050,Ie278f678
* changes: WM/SurfacePackage: Forward insets to WindowContainer overlays Reland "SurfaceControlViewHost: Restrict disclosure of input token""
-rw-r--r--core/java/android/view/ISurfaceControlViewHost.aidl3
-rw-r--r--core/java/android/view/IWindowSession.aidl2
-rw-r--r--core/java/android/view/SurfaceControlViewHost.java14
-rw-r--r--core/java/android/view/ViewRootImpl.java18
-rw-r--r--core/java/android/view/WindowlessWindowManager.java36
-rw-r--r--core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java122
-rw-r--r--services/core/java/com/android/server/wm/EmbeddedWindowController.java39
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java14
-rw-r--r--services/core/java/com/android/server/wm/OverlayHost.java12
-rw-r--r--services/core/java/com/android/server/wm/Session.java4
-rw-r--r--services/core/java/com/android/server/wm/Task.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java22
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
15 files changed, 293 insertions, 28 deletions
diff --git a/core/java/android/view/ISurfaceControlViewHost.aidl b/core/java/android/view/ISurfaceControlViewHost.aidl
index fc9661a0e61a..bf72a307220d 100644
--- a/core/java/android/view/ISurfaceControlViewHost.aidl
+++ b/core/java/android/view/ISurfaceControlViewHost.aidl
@@ -17,6 +17,8 @@
package android.view;
import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.view.InsetsState;
/**
* API from content embedder back to embedded content in SurfaceControlViewHost
@@ -25,4 +27,5 @@ import android.content.res.Configuration;
oneway interface ISurfaceControlViewHost {
void onConfigurationChanged(in Configuration newConfig);
void onDispatchDetachedFromWindow();
+ void onInsetsChanged(in InsetsState state, in Rect insetFrame);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index ccf1e44f8b6d..32054b1cdc13 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -298,7 +298,7 @@ interface IWindowSession {
*/
void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window,
in IBinder hostInputToken, int flags, int privateFlags, int type,
- out InputChannel outInputChannel);
+ in IBinder focusGrantToken, out InputChannel outInputChannel);
/**
* Update the flags on an input channel associated with a particular surface.
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 85a9dbd736ed..b461faf70296 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -22,10 +22,12 @@ import android.annotation.TestApi;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.accessibility.IAccessibilityEmbeddedConnection;
+import android.view.InsetsState;
import java.util.Objects;
@@ -71,6 +73,16 @@ public class SurfaceControlViewHost {
release();
});
}
+
+ @Override
+ public void onInsetsChanged(InsetsState state, Rect frame) {
+ if (mViewRoot != null) {
+ mViewRoot.mHandler.post(() -> {
+ mViewRoot.setOverrideInsetsFrame(frame);
+ });
+ }
+ mWm.setInsetsState(state);
+ }
}
private ISurfaceControlViewHost mRemoteInterface = new ISurfaceControlViewHostImpl();
@@ -274,7 +286,7 @@ public class SurfaceControlViewHost {
public @Nullable SurfacePackage getSurfacePackage() {
if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) {
return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection,
- mViewRoot.getInputToken(), mRemoteInterface);
+ mWm.getFocusGrantToken(), mRemoteInterface);
} else {
return null;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1496a4a7c6b3..eaa12e53c321 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -643,6 +643,7 @@ public final class ViewRootImpl implements ViewParent,
// These are accessed by multiple threads.
final Rect mWinFrame; // frame given by window manager.
+ Rect mOverrideInsetsFrame;
final Rect mPendingBackDropFrame = new Rect();
@@ -8069,7 +8070,22 @@ public final class ViewRootImpl implements ViewParent,
private void setFrame(Rect frame) {
mWinFrame.set(frame);
- mInsetsController.onFrameChanged(frame);
+ mInsetsController.onFrameChanged(mOverrideInsetsFrame != null ?
+ mOverrideInsetsFrame : frame);
+ }
+
+ /**
+ * In the normal course of operations we compute insets relative to
+ * the frame returned from relayout window. In the case of
+ * SurfaceControlViewHost, this frame is in local coordinates
+ * instead of global coordinates. We support this override
+ * frame so we can allow SurfaceControlViewHost to set a frame
+ * to be used to calculate insets, without disturbing the main
+ * mFrame.
+ */
+ void setOverrideInsetsFrame(Rect frame) {
+ mOverrideInsetsFrame = new Rect(frame);
+ mInsetsController.onFrameChanged(mOverrideInsetsFrame);
}
/**
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 3392edce479d..56f0915b785e 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -21,11 +21,14 @@ import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.util.MergedConfiguration;
+import android.view.InsetsState;
+import android.view.IWindow;
import android.window.ClientWindowFrames;
import android.window.IOnBackInvokedCallback;
@@ -48,12 +51,14 @@ public class WindowlessWindowManager implements IWindowSession {
int mDisplayId;
IBinder mInputChannelToken;
Region mInputRegion;
+ IWindow mClient;
State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId,
- IBinder inputChannelToken) {
+ IBinder inputChannelToken, IWindow client) {
mSurfaceControl = sc;
mParams.copyFrom(p);
mDisplayId = displayId;
mInputChannelToken = inputChannelToken;
+ mClient = client;
}
};
@@ -75,6 +80,8 @@ public class WindowlessWindowManager implements IWindowSession {
private final Configuration mConfiguration;
private final IWindowSession mRealWm;
private final IBinder mHostInputToken;
+ private final IBinder mFocusGrantToken = new Binder();
+ private InsetsState mInsetsState;
private int mForceHeight = -1;
private int mForceWidth = -1;
@@ -91,6 +98,10 @@ public class WindowlessWindowManager implements IWindowSession {
mConfiguration.setTo(configuration);
}
+ IBinder getFocusGrantToken() {
+ return mFocusGrantToken;
+ }
+
/**
* Utility API.
*/
@@ -153,10 +164,10 @@ public class WindowlessWindowManager implements IWindowSession {
mRealWm.grantInputChannel(displayId,
new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
window, mHostInputToken, attrs.flags, attrs.privateFlags, attrs.type,
- outInputChannel);
+ mFocusGrantToken, outInputChannel);
} else {
mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
- attrs.privateFlags, attrs.type, outInputChannel);
+ attrs.privateFlags, attrs.type, mFocusGrantToken, outInputChannel);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to grant input to surface: ", e);
@@ -164,7 +175,7 @@ public class WindowlessWindowManager implements IWindowSession {
}
final State state = new State(sc, attrs, displayId,
- outInputChannel != null ? outInputChannel.getToken() : null);
+ outInputChannel != null ? outInputChannel.getToken() : null, window);
synchronized (this) {
mStateForWindow.put(window.asBinder(), state);
}
@@ -312,6 +323,10 @@ public class WindowlessWindowManager implements IWindowSession {
}
}
+ if (mInsetsState != null) {
+ outInsetsState.set(mInsetsState);
+ }
+
// Include whether the window is in touch mode.
return isInTouchMode() ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
}
@@ -469,7 +484,7 @@ public class WindowlessWindowManager implements IWindowSession {
@Override
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
- IBinder hostInputToken, int flags, int privateFlags, int type,
+ IBinder hostInputToken, int flags, int privateFlags, int type, IBinder focusGrantToken,
InputChannel outInputChannel) {
}
@@ -501,4 +516,15 @@ public class WindowlessWindowManager implements IWindowSession {
public boolean dropForAccessibility(IWindow window, int x, int y) {
return false;
}
+
+ public void setInsetsState(InsetsState state) {
+ mInsetsState = state;
+ for (State s : mStateForWindow.values()) {
+ try {
+ s.mClient.insetsChanged(state, false, false);
+ } catch (RemoteException e) {
+ // Too bad
+ }
+ }
+ }
}
diff --git a/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java b/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java
new file mode 100644
index 000000000000..4731e8172dca
--- /dev/null
+++ b/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.view;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import static android.view.InsetsState.ITYPE_STATUS_BAR;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.graphics.Insets;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.platform.test.annotations.Presubmit;
+import android.view.InsetsState.InternalInsetsType;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.WindowInsets.Type;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class SurfaceControlViewHostInsetsTest {
+ SurfaceControlViewHost mSurfaceControlViewHost;
+ private boolean mStatusBarIsVisible = false;
+ private Insets mStatusBarInsets;
+ private Instrumentation mInstrumentation;
+
+ private void createViewHierarchy() {
+ Context context = mInstrumentation.getTargetContext();
+
+ View v = new View(context);
+ v.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
+ public WindowInsets onApplyWindowInsets(View v, WindowInsets w) {
+ mStatusBarIsVisible = w.isVisible(WindowInsets.Type.statusBars());
+ mStatusBarInsets = w.getInsets(WindowInsets.Type.statusBars());
+ return w;
+ }
+ });
+ mSurfaceControlViewHost = new SurfaceControlViewHost(context,
+ context.getDisplayNoVerify(), new Binder());
+ mSurfaceControlViewHost.setView(v, 100, 100);
+ }
+
+ @Before
+ public void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mInstrumentation.runOnMainSync(() -> { createViewHierarchy(); });
+ mInstrumentation.waitForIdleSync();
+ }
+
+ private InsetsState statusBarState(boolean visible) {
+ final InsetsState insetsState = new InsetsState();
+ insetsState.setDisplayFrame(new Rect(0, 0, 1000, 1000));
+ insetsState.getSource(ITYPE_STATUS_BAR).setVisible(visible);
+ insetsState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 10));
+ return insetsState;
+ }
+
+ private InsetsState statusBarVisibleState() {
+ return statusBarState(true);
+ }
+
+ private void sendInsetsSync(InsetsState s, Rect f) {
+ try {
+ mSurfaceControlViewHost.getSurfacePackage().getRemoteInterface()
+ .onInsetsChanged(s, f);
+ } catch (Exception e) {
+ }
+ mInstrumentation.waitForIdleSync();
+ }
+
+ @Test
+ public void sendInsetsToSurfaceControlViewHost() {
+ final InsetsState insetsState = statusBarVisibleState();
+ sendInsetsSync(insetsState, new Rect(0, 0, 100, 100));
+ assertTrue(mStatusBarIsVisible);
+
+ final InsetsState insetsState2 = statusBarState(false);
+ sendInsetsSync(insetsState2, new Rect(0, 0, 100, 100));
+ assertFalse(mStatusBarIsVisible);
+ }
+
+ @Test
+ public void insetsAreRelativeToFrame() {
+ final InsetsState insetsState = statusBarVisibleState();
+ sendInsetsSync(insetsState, new Rect(0, 0, 100, 100));
+
+ assertTrue(mStatusBarIsVisible);
+ assertEquals(10, mStatusBarInsets.top);
+
+ sendInsetsSync(insetsState, new Rect(0, 5, 100, 100));
+ assertEquals(5, mStatusBarInsets.top);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 0e2d84779602..8db43066eae5 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -41,6 +41,8 @@ class EmbeddedWindowController {
private static final String TAG = TAG_WITH_CLASS_NAME ? "EmbeddedWindowController" : TAG_WM;
/* maps input token to an embedded window */
private ArrayMap<IBinder /*input token */, EmbeddedWindow> mWindows = new ArrayMap<>();
+ private ArrayMap<IBinder /*focus grant token */, EmbeddedWindow> mWindowsByFocusToken =
+ new ArrayMap<>();
private final Object mGlobalLock;
private final ActivityTaskManagerService mAtmService;
@@ -59,10 +61,13 @@ class EmbeddedWindowController {
void add(IBinder inputToken, EmbeddedWindow window) {
try {
mWindows.put(inputToken, window);
+ final IBinder focusToken = window.getFocusGrantToken();
+ mWindowsByFocusToken.put(focusToken, window);
updateProcessController(window);
window.mClient.asBinder().linkToDeath(()-> {
synchronized (mGlobalLock) {
mWindows.remove(inputToken);
+ mWindowsByFocusToken.remove(focusToken);
}
}, 0);
} catch (RemoteException e) {
@@ -98,8 +103,8 @@ class EmbeddedWindowController {
return embeddedWindow != null ? embeddedWindow.getIsOverlay() : false;
}
- void setIsOverlay(IBinder inputToken) {
- EmbeddedWindow embeddedWindow = mWindows.get(inputToken);
+ void setIsOverlay(IBinder focusGrantToken) {
+ EmbeddedWindow embeddedWindow = mWindowsByFocusToken.get(focusGrantToken);
if (embeddedWindow != null) {
embeddedWindow.setIsOverlay();
}
@@ -107,8 +112,10 @@ class EmbeddedWindowController {
void remove(IWindow client) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
- if (mWindows.valueAt(i).mClient.asBinder() == client.asBinder()) {
+ EmbeddedWindow ew = mWindows.valueAt(i);
+ if (ew.mClient.asBinder() == client.asBinder()) {
mWindows.removeAt(i).onRemoved();
+ mWindowsByFocusToken.remove(ew.getFocusGrantToken());
return;
}
}
@@ -116,8 +123,10 @@ class EmbeddedWindowController {
void onWindowRemoved(WindowState host) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
- if (mWindows.valueAt(i).mHostWindowState == host) {
+ EmbeddedWindow ew = mWindows.valueAt(i);
+ if (ew.mHostWindowState == host) {
mWindows.removeAt(i).onRemoved();
+ mWindowsByFocusToken.remove(ew.getFocusGrantToken());
}
}
}
@@ -126,6 +135,10 @@ class EmbeddedWindowController {
return mWindows.get(inputToken);
}
+ EmbeddedWindow getByFocusToken(IBinder focusGrantToken) {
+ return mWindowsByFocusToken.get(focusGrantToken);
+ }
+
void onActivityRemoved(ActivityRecord activityRecord) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
final EmbeddedWindow window = mWindows.valueAt(i);
@@ -157,6 +170,8 @@ class EmbeddedWindowController {
// and this variable is mostly used for tracking that.
boolean mIsOverlay = false;
+ private IBinder mFocusGrantToken;
+
/**
* @param session calling session to check ownership of the window
* @param clientToken client token used to clean up the map if the embedding process dies
@@ -171,7 +186,7 @@ class EmbeddedWindowController {
*/
EmbeddedWindow(Session session, WindowManagerService service, IWindow clientToken,
WindowState hostWindowState, int ownerUid, int ownerPid, int windowType,
- int displayId) {
+ int displayId, IBinder focusGrantToken) {
mSession = session;
mWmService = service;
mClient = clientToken;
@@ -182,6 +197,7 @@ class EmbeddedWindowController {
mOwnerPid = ownerPid;
mWindowType = windowType;
mDisplayId = displayId;
+ mFocusGrantToken = focusGrantToken;
}
@Override
@@ -242,6 +258,17 @@ class EmbeddedWindowController {
return mIsOverlay;
}
+ IBinder getFocusGrantToken() {
+ return mFocusGrantToken;
+ }
+
+ IBinder getInputChannelToken() {
+ if (mInputChannel != null) {
+ return mInputChannel.getToken();
+ }
+ return null;
+ }
+
/**
* System hosted overlays need the WM to invoke grantEmbeddedWindowFocus and
* so we need to participate inside handlePointerDownOutsideFocus logic
@@ -255,7 +282,7 @@ class EmbeddedWindowController {
private void handleTap(boolean grantFocus) {
if (mInputChannel != null) {
- mWmService.grantEmbeddedWindowFocus(mSession, mInputChannel.getToken(), grantFocus);
+ mWmService.grantEmbeddedWindowFocus(mSession, mFocusGrantToken, grantFocus);
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 9326a2ebb331..10776abee51e 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -219,13 +219,23 @@ class InsetsPolicy {
/**
* @see InsetsStateController#getInsetsForWindow
*/
- InsetsState getInsetsForWindow(WindowState target) {
+ InsetsState getInsetsForWindow(WindowState target, boolean includesTransient) {
final InsetsState originalState = mStateController.getInsetsForWindow(target);
- InsetsState state = adjustVisibilityForTransientTypes(originalState);
+ InsetsState state;
+ if (!includesTransient) {
+ state = adjustVisibilityForTransientTypes(originalState);
+ } else {
+ state = originalState;
+ }
state = adjustVisibilityForIme(target, state, state == originalState);
return adjustInsetsForRoundedCorners(target, state, state == originalState);
}
+ InsetsState getInsetsForWindow(WindowState target) {
+ return getInsetsForWindow(target, false);
+ }
+
+
/**
* @see InsetsStateController#getInsetsForWindowMetrics
*/
diff --git a/services/core/java/com/android/server/wm/OverlayHost.java b/services/core/java/com/android/server/wm/OverlayHost.java
index 724e1247b100..90f5b09968ea 100644
--- a/services/core/java/com/android/server/wm/OverlayHost.java
+++ b/services/core/java/com/android/server/wm/OverlayHost.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.view.InsetsState;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
@@ -121,6 +123,16 @@ class OverlayHost {
}
}
+ void dispatchInsetsChanged(InsetsState s, Rect insetFrame) {
+ for (int i = mOverlays.size() - 1; i >= 0; i--) {
+ SurfaceControlViewHost.SurfacePackage l = mOverlays.get(i);
+ try {
+ l.getRemoteInterface().onInsetsChanged(s, insetFrame);
+ } catch (Exception e) {
+ }
+ }
+ }
+
void release() {
dispatchDetachedFromWindow();
mOverlays.clear();
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9b94f44be714..98acc4607d18 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -813,7 +813,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
@Override
public void grantInputChannel(int displayId, SurfaceControl surface,
IWindow window, IBinder hostInputToken, int flags, int privateFlags, int type,
- InputChannel outInputChannel) {
+ IBinder focusGrantToken, InputChannel outInputChannel) {
if (hostInputToken == null && !mCanAddInternalSystemWindow) {
// Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
// embedded windows without providing a host window input token
@@ -829,7 +829,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
try {
mService.grantInputChannel(this, mUid, mPid, displayId, surface, window, hostInputToken,
flags, mCanAddInternalSystemWindow ? privateFlags : 0,
- mCanAddInternalSystemWindow ? type : 0, outInputChannel);
+ mCanAddInternalSystemWindow ? type : 0, focusGrantToken, outInputChannel);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 91c13746f726..7d06526e18b5 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6588,4 +6588,18 @@ class Task extends TaskFragment {
mLaunchCookie, mDeferTaskAppear, mRemoveWithTaskOrganizer);
}
}
+
+ @Override
+ void updateOverlayInsetsState(WindowState originalChange) {
+ super.updateOverlayInsetsState(originalChange);
+ if (originalChange != getTopVisibleAppMainWindow()) {
+ return;
+ }
+ if (mOverlayHost != null) {
+ final InsetsState s = getDisplayContent().getInsetsPolicy()
+ .getInsetsForWindow(originalChange, true);
+ getBounds(mTmpRect);
+ mOverlayHost.dispatchInsetsChanged(s, mTmpRect);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 08130b621f1a..1bd153b2a577 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -81,6 +81,7 @@ import android.util.Pools;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
+import android.view.InsetsState;
import android.view.MagnificationSpec;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationTarget;
@@ -313,7 +314,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
private final List<WindowContainerListener> mListeners = new ArrayList<>();
- private OverlayHost mOverlayHost;
+ protected OverlayHost mOverlayHost;
WindowContainer(WindowManagerService wms) {
mWmService = wms;
@@ -3622,4 +3623,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
mOverlayHost = null;
}
}
+
+ void updateOverlayInsetsState(WindowState originalChange) {
+ final WindowContainer p = getParent();
+ if (p != null) {
+ p.updateOverlayInsetsState(originalChange);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index ee0af9d786eb..20fa7a9da256 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -797,7 +797,12 @@ public abstract class WindowManagerInternal {
* Callers prepare a view hierarchy with SurfaceControlViewHost
* and send the package to WM here. The remote view hierarchy will receive
* configuration change, lifecycle events, etc, forwarded over the
- * ISurfaceControlViewHost interface inside the SurfacePackage.
+ * ISurfaceControlViewHost interface inside the SurfacePackage. Embedded
+ * hierarchies will receive inset changes, including transient inset changes
+ * (to avoid the status bar in immersive mode).
+ *
+ * The embedded hierarchy exists in a coordinate space relative to the task
+ * bounds.
*/
public abstract void addTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay);
public abstract void removeTaskOverlay(int taskId, SurfaceControlViewHost.SurfacePackage overlay);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 056b0ed4f504..b37cb4f286f9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8303,7 +8303,8 @@ public class WindowManagerService extends IWindowManager.Stub
*/
void grantInputChannel(Session session, int callingUid, int callingPid, int displayId,
SurfaceControl surface, IWindow window, IBinder hostInputToken,
- int flags, int privateFlags, int type, InputChannel outInputChannel) {
+ int flags, int privateFlags, int type, IBinder focusGrantToken,
+ InputChannel outInputChannel) {
final InputApplicationHandle applicationHandle;
final String name;
final InputChannel clientChannel;
@@ -8311,7 +8312,7 @@ public class WindowManagerService extends IWindowManager.Stub
EmbeddedWindowController.EmbeddedWindow win =
new EmbeddedWindowController.EmbeddedWindow(session, this, window,
mInputToWindowMap.get(hostInputToken), callingUid, callingPid, type,
- displayId);
+ displayId, focusGrantToken);
clientChannel = win.openInputChannel();
mEmbeddedWindowController.add(clientChannel.getToken(), win);
applicationHandle = win.getApplicationHandle();
@@ -8590,10 +8591,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- void grantEmbeddedWindowFocus(Session session, IBinder inputToken, boolean grantFocus) {
+ void grantEmbeddedWindowFocus(Session session, IBinder focusToken, boolean grantFocus) {
synchronized (mGlobalLock) {
final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
- mEmbeddedWindowController.get(inputToken);
+ mEmbeddedWindowController.getByFocusToken(focusToken);
if (embeddedWindow == null) {
Slog.e(TAG, "Embedded window not found");
return;
@@ -8602,6 +8603,11 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.e(TAG, "Window not in session:" + session);
return;
}
+ IBinder inputToken = embeddedWindow.getInputChannelToken();
+ if (inputToken == null) {
+ Slog.e(TAG, "Focus token found but input channel token not found");
+ return;
+ }
SurfaceControl.Transaction t = mTransactionFactory.get();
final int displayId = embeddedWindow.mDisplayId;
if (grantFocus) {
@@ -8631,7 +8637,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- void grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetInputToken,
+ void grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetFocusToken,
boolean grantFocus) {
synchronized (mGlobalLock) {
final WindowState hostWindow =
@@ -8645,7 +8651,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
- mEmbeddedWindowController.get(targetInputToken);
+ mEmbeddedWindowController.getByFocusToken(targetFocusToken);
if (embeddedWindow == null) {
Slog.e(TAG, "Embedded window not found");
return;
@@ -8656,7 +8662,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
SurfaceControl.Transaction t = mTransactionFactory.get();
if (grantFocus) {
- t.requestFocusTransfer(targetInputToken, embeddedWindow.toString(),
+ t.requestFocusTransfer(embeddedWindow.getInputChannelToken(), embeddedWindow.toString(),
hostWindow.mInputChannel.getToken(),
hostWindow.getName(),
hostWindow.getDisplayId()).apply();
@@ -8665,7 +8671,7 @@ public class WindowManagerService extends IWindowManager.Stub
"reason=grantEmbeddedWindowFocus(true)");
} else {
t.requestFocusTransfer(hostWindow.mInputChannel.getToken(), hostWindow.getName(),
- targetInputToken,
+ embeddedWindow.getInputChannelToken(),
embeddedWindow.toString(),
hostWindow.getDisplayId()).apply();
EventLog.writeEvent(LOGTAG_INPUT_FOCUS,
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 8864b9847ff8..0a02b4442518 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3848,6 +3848,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver inset state change w=" + this, e);
}
+ final WindowContainer p = getParent();
+ if (p != null) {
+ p.updateOverlayInsetsState(this);
+ }
}
@Override