summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/WindowlessWindowManager.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java24
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java21
-rw-r--r--services/core/java/com/android/server/wm/EmbeddedWindowController.java31
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java37
-rw-r--r--services/core/java/com/android/server/wm/InputTarget.java6
-rw-r--r--services/core/java/com/android/server/wm/InsetsControlTarget.java16
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java4
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java36
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java4
-rw-r--r--services/core/java/com/android/server/wm/InsetsTarget.java48
-rw-r--r--services/core/java/com/android/server/wm/Session.java21
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java37
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java2
14 files changed, 218 insertions, 78 deletions
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index d2747e465071..5129461095a3 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -587,7 +587,14 @@ public class WindowlessWindowManager implements IWindowSession {
@Override
public void updateRequestedVisibleTypes(IWindow window,
- @InsetsType int requestedVisibleTypes, @Nullable ImeTracker.Token imeStatsToken) {
+ @InsetsType int requestedVisibleTypes, @Nullable ImeTracker.Token imeStatsToken)
+ throws RemoteException {
+ if (android.view.inputmethod.Flags.refactorInsetsController()) {
+ // Embedded windows do not control insets (except for IME). The host window is
+ // responsible for controlling the insets.
+ mRealWm.updateRequestedVisibleTypes(window,
+ requestedVisibleTypes & WindowInsets.Type.ime(), imeStatsToken);
+ }
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index f03daada4ca0..c4082d9f649c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -303,21 +303,29 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
lastSurfacePosition);
} else {
if (!haveSameLeash(mImeSourceControl, imeSourceControl)) {
- applyVisibilityToLeash(imeSourceControl);
-
if (android.view.inputmethod.Flags.refactorInsetsController()) {
pendingImeStartAnimation = true;
+ // The starting point for the IME should be it's previous state
+ // (whether it is initiallyVisible or not)
+ updateImeVisibility(imeSourceControl.isInitiallyVisible());
}
+ applyVisibilityToLeash(imeSourceControl);
}
if (!mImeShowing) {
removeImeSurface(mDisplayId);
}
}
- } else if (!android.view.inputmethod.Flags.refactorInsetsController()
- && mAnimation != null) {
- // we don"t want to cancel the hide animation, when the control is lost, but
- // continue the bar to slide to the end (even without visible IME)
- mAnimation.cancel();
+ } else {
+ if (!android.view.inputmethod.Flags.refactorInsetsController()
+ && mAnimation != null) {
+ // we don't want to cancel the hide animation, when the control is lost, but
+ // continue the bar to slide to the end (even without visible IME)
+ mAnimation.cancel();
+ } else if (android.view.inputmethod.Flags.refactorInsetsController() && mImeShowing
+ && mAnimation == null) {
+ // There is no leash, so the IME cannot be in a showing state
+ updateImeVisibility(false);
+ }
}
// Make mImeSourceControl point to the new control before starting the animation.
@@ -341,7 +349,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
if (android.view.inputmethod.Flags.refactorInsetsController()) {
if (pendingImeStartAnimation) {
- startAnimation(true, true /* forceRestart */);
+ startAnimation(mImeRequestedVisible, true /* forceRestart */);
}
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 10e0641b0582..21212e573ffa 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -707,6 +707,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@Retention(RetentionPolicy.SOURCE)
@interface InputMethodTarget {}
+ /** The surface parent window of the IME container. */
+ private WindowContainer mInputMethodSurfaceParentWindow;
/** The surface parent of the IME container. */
@VisibleForTesting
SurfaceControl mInputMethodSurfaceParent;
@@ -1529,6 +1531,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return mDisplayRotation.getLastOrientation();
}
+ WindowContainer getImeParentWindow() {
+ return mInputMethodSurfaceParentWindow;
+ }
+
void registerRemoteAnimations(RemoteAnimationDefinition definition) {
mAppTransitionController.registerRemoteAnimations(definition);
}
@@ -4733,13 +4739,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
Slog.i(TAG_WM, "ImeContainer is organized. Skip updateImeParent.");
}
// Leave the ImeContainer where the DisplayAreaPolicy placed it.
- // FEATURE_IME is organized by vendor so they are responible for placing the surface.
+ // FEATURE_IME is organized by vendor so they are responsible for placing the surface.
+ mInputMethodSurfaceParentWindow = null;
mInputMethodSurfaceParent = null;
return;
}
- final SurfaceControl newParent = computeImeParent();
+ final var newParentWindow = computeImeParent();
+ final SurfaceControl newParent =
+ newParentWindow != null ? newParentWindow.getSurfaceControl() : null;
if (newParent != null && newParent != mInputMethodSurfaceParent) {
+ mInputMethodSurfaceParentWindow = newParentWindow;
mInputMethodSurfaceParent = newParent;
getSyncTransaction().reparent(mImeWindowsContainer.mSurfaceControl, newParent);
if (DEBUG_IME_VISIBILITY) {
@@ -4800,7 +4810,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
* Computes the window the IME should be attached to.
*/
@VisibleForTesting
- SurfaceControl computeImeParent() {
+ WindowContainer computeImeParent() {
if (!ImeTargetVisibilityPolicy.canComputeImeParent(mImeLayeringTarget, mImeInputTarget)) {
return null;
}
@@ -4808,11 +4818,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// screen. If it's not covering the entire screen the IME might extend beyond the apps
// bounds.
if (shouldImeAttachedToApp()) {
- return mImeLayeringTarget.mActivityRecord.getSurfaceControl();
+ return mImeLayeringTarget.mActivityRecord;
}
// Otherwise, we just attach it to where the display area policy put it.
- return mImeWindowsContainer.getParent() != null
- ? mImeWindowsContainer.getParent().getSurfaceControl() : null;
+ return mImeWindowsContainer.getParent();
}
void setLayoutNeeded() {
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 169a76fe3afd..5514294ed477 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -33,6 +33,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
+import android.view.WindowInsets;
import android.window.InputTransferToken;
import com.android.internal.protolog.ProtoLog;
@@ -222,6 +223,10 @@ class EmbeddedWindowController {
private boolean mIsFocusable;
+ // The EmbeddedWindow can only request the IME. All other insets types are requested by
+ // the host window.
+ private @WindowInsets.Type.InsetsType int mRequestedVisibleTypes = 0;
+
/**
* @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
@@ -311,6 +316,27 @@ class EmbeddedWindowController {
}
@Override
+ public boolean isRequestedVisible(@WindowInsets.Type.InsetsType int types) {
+ return (mRequestedVisibleTypes & types) != 0;
+ }
+
+ @Override
+ public @WindowInsets.Type.InsetsType int getRequestedVisibleTypes() {
+ return mRequestedVisibleTypes;
+ }
+
+ /**
+ * Only the IME can be requested from the EmbeddedWindow.
+ * @param requestedVisibleTypes other types than {@link WindowInsets.Type.IME} are
+ * not sent to system server via WindowlessWindowManager.
+ */
+ void setRequestedVisibleTypes(@WindowInsets.Type.InsetsType int requestedVisibleTypes) {
+ if (mRequestedVisibleTypes != requestedVisibleTypes) {
+ mRequestedVisibleTypes = requestedVisibleTypes;
+ }
+ }
+
+ @Override
public int getPid() {
return mOwnerPid;
}
@@ -375,6 +401,11 @@ class EmbeddedWindowController {
@Override
public boolean shouldControlIme() {
+ if (android.view.inputmethod.Flags.refactorInsetsController()) {
+ // EmbeddedWindow should never be able to control the IME directly, but only the
+ // RemoteInsetsControlTarget.
+ return false;
+ }
return mHostWindowState != null;
}
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 43c3d05ac49d..e178203fed92 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -268,7 +268,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
// TODO(b/353463205) change statsToken to be NonNull, after the flag is permanently enabled
@Override
- protected boolean updateClientVisibility(InsetsControlTarget caller,
+ protected boolean updateClientVisibility(InsetsTarget caller,
@Nullable ImeTracker.Token statsToken) {
InsetsControlTarget controlTarget = getControlTarget();
if (caller != controlTarget) {
@@ -283,12 +283,13 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY);
controlTarget.setImeInputTargetRequestedVisibility(imeVisible);
- } else {
+ } else if (caller instanceof InsetsControlTarget) {
// In case of a virtual display that cannot show the IME, the
// controlTarget will be null here, as no controlTarget was set yet. In
// that case, proceed similar to the multi window mode (fallback =
// RemoteInsetsControlTarget of the default display)
- controlTarget = mDisplayContent.getImeHostOrFallback(caller.getWindow());
+ controlTarget = mDisplayContent.getImeHostOrFallback(
+ ((InsetsControlTarget) caller).getWindow());
if (controlTarget != caller) {
ImeTracker.forLogging().onProgress(statsToken,
@@ -300,8 +301,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
}
}
- WindowState windowState = caller.getWindow();
- invokeOnImeRequestedChangedListener(windowState, statsToken);
+ invokeOnImeRequestedChangedListener(caller, statsToken);
} else {
// TODO(b/353463205) add ImeTracker?
}
@@ -309,20 +309,16 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
return false;
}
boolean changed = super.updateClientVisibility(caller, statsToken);
- if (!Flags.refactorInsetsController()) {
+ if (!Flags.refactorInsetsController() && caller instanceof InsetsControlTarget) {
if (changed && caller.isRequestedVisible(mSource.getType())) {
- reportImeDrawnForOrganizerIfNeeded(caller);
+ reportImeDrawnForOrganizerIfNeeded((InsetsControlTarget) caller);
}
}
changed |= mDisplayContent.onImeInsetsClientVisibilityUpdate();
if (Flags.refactorInsetsController()) {
if (changed) {
- // RemoteInsetsControlTarget does not have a window. In this case, we use the
- // windowState from the imeInputTarget
- WindowState windowState = caller.getWindow() != null ? caller.getWindow()
- : ((mDisplayContent.getImeInputTarget() != null)
- ? mDisplayContent.getImeInputTarget().getWindowState() : null);
- invokeOnImeRequestedChangedListener(windowState, statsToken);
+ invokeOnImeRequestedChangedListener(mDisplayContent.getImeInputTarget(),
+ statsToken);
} else {
// TODO(b/329229469) change phase and check cancelled / failed
ImeTracker.forLogging().onCancelled(statsToken,
@@ -334,32 +330,31 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
void onInputTargetChanged(InputTarget target) {
if (Flags.refactorInsetsController() && target != null) {
- WindowState targetWin = target.getWindowState();
InsetsControlTarget imeControlTarget = getControlTarget();
- if (target != imeControlTarget && targetWin != null) {
+ if (target != imeControlTarget) {
// If the targetWin is not the imeControlTarget (=RemoteInsetsControlTarget) let it
// know about the new requestedVisibleTypes for the IME.
if (imeControlTarget != null) {
imeControlTarget.setImeInputTargetRequestedVisibility(
- (targetWin.getRequestedVisibleTypes() & WindowInsets.Type.ime()) != 0);
+ (target.getRequestedVisibleTypes() & WindowInsets.Type.ime()) != 0);
}
}
}
}
// TODO(b/353463205) check callers to see if we can make statsToken @NonNull
- private void invokeOnImeRequestedChangedListener(WindowState windowState,
+ private void invokeOnImeRequestedChangedListener(InsetsTarget insetsTarget,
@Nullable ImeTracker.Token statsToken) {
final var imeListener = mDisplayContent.mWmService.mOnImeRequestedChangedListener;
if (imeListener != null) {
- if (windowState != null) {
+ if (insetsTarget != null) {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_POSTING_CHANGED_IME_VISIBILITY);
mDisplayContent.mWmService.mH.post(() -> {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER);
- imeListener.onImeRequestedChanged(windowState.mClient.asBinder(),
- windowState.isRequestedVisible(WindowInsets.Type.ime()), statsToken);
+ imeListener.onImeRequestedChanged(insetsTarget.getWindowToken(),
+ insetsTarget.isRequestedVisible(WindowInsets.Type.ime()), statsToken);
});
} else {
ImeTracker.forLogging().onFailed(statsToken,
@@ -676,7 +671,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
return target == mDisplayContent.getImeFallback();
}
- private boolean isImeInputTarget(@NonNull InsetsControlTarget target) {
+ private boolean isImeInputTarget(@NonNull InsetsTarget target) {
return target == mDisplayContent.getImeInputTarget();
}
diff --git a/services/core/java/com/android/server/wm/InputTarget.java b/services/core/java/com/android/server/wm/InputTarget.java
index 0c0b794182e7..40ce9db8a608 100644
--- a/services/core/java/com/android/server/wm/InputTarget.java
+++ b/services/core/java/com/android/server/wm/InputTarget.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import android.os.IBinder;
import android.util.proto.ProtoOutputStream;
/**
@@ -25,16 +24,13 @@ import android.util.proto.ProtoOutputStream;
* Both WindowState and EmbeddedWindows can receive input. This consolidates some common properties
* of both targets.
*/
-interface InputTarget {
+interface InputTarget extends InsetsTarget {
/* Get the WindowState associated with the target. */
WindowState getWindowState();
/* Display id of the target. */
int getDisplayId();
- /* Client IWindow for the target. */
- IBinder getWindowToken();
-
/* Owning pid of the target. */
int getPid();
int getUid();
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index 07e249a2004f..7043aacfc44d 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
+import android.os.IBinder;
import android.view.WindowInsets;
import android.view.WindowInsets.Type.InsetsType;
import android.view.inputmethod.ImeTracker;
@@ -25,7 +26,7 @@ import android.view.inputmethod.ImeTracker;
/**
* Generalization of an object that can control insets state.
*/
-interface InsetsControlTarget {
+interface InsetsControlTarget extends InsetsTarget {
/**
* Notifies the control target that the insets control has changed.
@@ -42,16 +43,17 @@ interface InsetsControlTarget {
return null;
}
- /**
- * @return {@code true} if any of the {@link InsetsType} is requested visible by this target.
- */
+ @Override
+ default IBinder getWindowToken() {
+ return null;
+ }
+
+ @Override
default boolean isRequestedVisible(@InsetsType int types) {
return (WindowInsets.Type.defaultVisible() & types) != 0;
}
- /**
- * @return {@link InsetsType}s which are requested visible by this target.
- */
+ @Override
default @InsetsType int getRequestedVisibleTypes() {
return WindowInsets.Type.defaultVisible();
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 129078b0a235..b414a862f874 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -434,7 +434,7 @@ class InsetsPolicy {
return originalState;
}
- void onRequestedVisibleTypesChanged(InsetsControlTarget caller,
+ void onRequestedVisibleTypesChanged(InsetsTarget caller,
@Nullable ImeTracker.Token statsToken) {
mStateController.onRequestedVisibleTypesChanged(caller, statsToken);
checkAbortTransient(caller);
@@ -449,7 +449,7 @@ class InsetsPolicy {
*
* @param caller who changed the insets state.
*/
- private void checkAbortTransient(InsetsControlTarget caller) {
+ private void checkAbortTransient(InsetsTarget caller) {
if (mShowingTransientTypes == 0) {
return;
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 8f90b2d183e8..f0a4763796e3 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -529,13 +529,27 @@ class InsetsSourceProvider {
setClientVisible((WindowInsets.Type.defaultVisible() & mSource.getType()) != 0);
return;
}
+ boolean initiallyVisible = mClientVisible;
final Point surfacePosition = getWindowFrameSurfacePosition();
mAdapter = new ControlAdapter(surfacePosition);
if (mSource.getType() == WindowInsets.Type.ime()) {
+ if (android.view.inputmethod.Flags.refactorInsetsController()) {
+ if (mClientVisible && mServerVisible) {
+ WindowContainer imeParentWindow = mDisplayContent.getImeParentWindow();
+ // If the IME is attached to an app window, only consider it initially visible
+ // if the parent is visible and wasn't part of a transition.
+ initiallyVisible =
+ imeParentWindow != null && !imeParentWindow.inTransitionSelfOrParent()
+ && imeParentWindow.isVisible()
+ && imeParentWindow.isVisibleRequested();
+ } else {
+ initiallyVisible = false;
+ }
+ }
setClientVisible(target.isRequestedVisible(WindowInsets.Type.ime()));
}
final Transaction t = mWindowContainer.getSyncTransaction();
- mWindowContainer.startAnimation(t, mAdapter, !mClientVisible /* hidden */,
+ mWindowContainer.startAnimation(t, mAdapter, !initiallyVisible /* hidden */,
ANIMATION_TYPE_INSETS_CONTROL);
// The leash was just created. We cannot dispatch it until its surface transaction is
@@ -545,14 +559,16 @@ class InsetsSourceProvider {
final SurfaceControl leash = mAdapter.mCapturedLeash;
mControlTarget = target;
updateVisibility();
- boolean initiallyVisible = mClientVisible;
if (mSource.getType() == WindowInsets.Type.ime()) {
- // The IME cannot be initially visible, see ControlAdapter#startAnimation below.
- // Also, the ImeInsetsSourceConsumer clears the client visibility upon losing control,
- // but this won't have reached here yet by the time the new control is created.
- // Note: The DisplayImeController needs the correct previous client's visibility, so we
- // only override the initiallyVisible here.
- initiallyVisible = false;
+ if (!android.view.inputmethod.Flags.refactorInsetsController()) {
+ // The IME cannot be initially visible, see ControlAdapter#startAnimation below.
+ // Also, the ImeInsetsSourceConsumer clears the client visibility upon losing
+ // control, but this won't have reached here yet by the time the new control is
+ // created.
+ // Note: The DisplayImeController needs the correct previous client's visibility,
+ // so we only override the initiallyVisible here.
+ initiallyVisible = false;
+ }
}
mControl = new InsetsSourceControl(mSource.getId(), mSource.getType(), leash,
initiallyVisible, surfacePosition, getInsetsHint());
@@ -598,7 +614,7 @@ class InsetsSourceProvider {
mSeamlessRotating = false;
}
- boolean updateClientVisibility(InsetsControlTarget caller,
+ boolean updateClientVisibility(InsetsTarget caller,
@Nullable ImeTracker.Token statsToken) {
final boolean requestedVisible = caller.isRequestedVisible(mSource.getType());
if (caller != mControlTarget || requestedVisible == mClientVisible) {
@@ -799,7 +815,7 @@ class InsetsSourceProvider {
@AnimationType int type, @NonNull OnAnimationFinishedCallback finishCallback) {
// TODO(b/166736352): Check if we still need to control the IME visibility here.
if (mSource.getType() == WindowInsets.Type.ime()) {
- if (!android.view.inputmethod.Flags.refactorInsetsController() || !mClientVisible) {
+ if (!android.view.inputmethod.Flags.refactorInsetsController()) {
// TODO: use 0 alpha and remove t.hide() once b/138459974 is fixed.
t.setAlpha(animationLeash, 1 /* alpha */);
t.hide(animationLeash);
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 481ecd3447f1..3e39a45fa5f3 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -219,7 +219,7 @@ class InsetsStateController {
}
}
- void onRequestedVisibleTypesChanged(InsetsControlTarget caller,
+ void onRequestedVisibleTypesChanged(InsetsTarget caller,
@Nullable ImeTracker.Token statsToken) {
boolean changed = false;
for (int i = mProviders.size() - 1; i >= 0; i--) {
@@ -238,7 +238,7 @@ class InsetsStateController {
}
}
- @InsetsType int getFakeControllingTypes(InsetsControlTarget target) {
+ @InsetsType int getFakeControllingTypes(InsetsTarget target) {
@InsetsType int types = 0;
for (int i = mProviders.size() - 1; i >= 0; i--) {
final InsetsSourceProvider provider = mProviders.valueAt(i);
diff --git a/services/core/java/com/android/server/wm/InsetsTarget.java b/services/core/java/com/android/server/wm/InsetsTarget.java
new file mode 100644
index 000000000000..b918ca3dbff6
--- /dev/null
+++ b/services/core/java/com/android/server/wm/InsetsTarget.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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 com.android.server.wm;
+
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.view.WindowInsets;
+
+/**
+ * A common parent for {@link InputTarget} and {@link InsetsControlTarget}: Some types (like the
+ * {@link EmbeddedWindowController.EmbeddedWindow}) should not be a control target for insets in
+ * general, but should be able to request the IME. To archive this, the InsetsTarget contains the
+ * minimal information that those interfaces share (and what is needed to show the IME.
+ */
+public interface InsetsTarget {
+
+ /**
+ * @return Client IWindow token for the target.
+ */
+ @Nullable
+ IBinder getWindowToken();
+
+ /**
+ * @param types The {@link WindowInsets.Type}s which requestedVisibility status is returned.
+ * @return {@code true} if any of the {@link WindowInsets.Type.InsetsType} is requested
+ * visible by this target.
+ */
+ boolean isRequestedVisible(@WindowInsets.Type.InsetsType int types);
+
+ /**
+ * @return {@link WindowInsets.Type.InsetsType}s which are requested visible by this target.
+ */
+ @WindowInsets.Type.InsetsType int getRequestedVisibleTypes();
+}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 2ea2aeb6b74e..5550f3efaa3a 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -705,8 +705,25 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
win.getDisplayContent().getInsetsPolicy().onRequestedVisibleTypesChanged(win,
imeStatsToken);
} else {
- ImeTracker.forLogging().onFailed(imeStatsToken,
- ImeTracker.PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES);
+ EmbeddedWindowController.EmbeddedWindow embeddedWindow = null;
+ if (android.view.inputmethod.Flags.refactorInsetsController()) {
+ embeddedWindow = mService.mEmbeddedWindowController.getByWindowToken(
+ window.asBinder());
+ }
+ if (embeddedWindow != null) {
+ // If there is no WindowState for the IWindow, it could be still an
+ // EmbeddedWindow. Therefore, check the EmbeddedWindowController as well
+ // TODO(b/329229469) Use different phase here
+ ImeTracker.forLogging().onProgress(imeStatsToken,
+ ImeTracker.PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES);
+ embeddedWindow.setRequestedVisibleTypes(
+ requestedVisibleTypes & WindowInsets.Type.ime());
+ embeddedWindow.getDisplayContent().getInsetsPolicy()
+ .onRequestedVisibleTypesChanged(embeddedWindow, imeStatsToken);
+ } else {
+ ImeTracker.forLogging().onFailed(imeStatsToken,
+ ImeTracker.PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES);
+ }
}
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index eca4d21a974e..85cb1bcc01fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -369,8 +369,10 @@ public class DisplayContentTests extends WindowTestsBase {
"startingWin");
startingWin.setHasSurface(true);
assertTrue(startingWin.canBeImeTarget());
+ final WindowContainer imeSurfaceParentWindow = mock(WindowContainer.class);
final SurfaceControl imeSurfaceParent = mock(SurfaceControl.class);
- doReturn(imeSurfaceParent).when(mDisplayContent).computeImeParent();
+ doReturn(imeSurfaceParent).when(imeSurfaceParentWindow).getSurfaceControl();
+ doReturn(imeSurfaceParentWindow).when(mDisplayContent).computeImeParent();
spyOn(imeContainer);
mDisplayContent.setImeInputTarget(startingWin);
@@ -406,8 +408,11 @@ public class DisplayContentTests extends WindowTestsBase {
"startingWin");
startingWin.setHasSurface(true);
assertTrue(startingWin.canBeImeTarget());
+ final WindowContainer imeSurfaceParentWindow = mock(WindowContainer.class);
final SurfaceControl imeSurfaceParent = mock(SurfaceControl.class);
- doReturn(imeSurfaceParent).when(mDisplayContent).computeImeParent();
+ doReturn(imeSurfaceParent).when(imeSurfaceParentWindow).getSurfaceControl();
+ doReturn(imeSurfaceParentWindow).when(mDisplayContent).computeImeParent();
+
// Main precondition for this test: organize the ImeContainer.
final IDisplayAreaOrganizer mockImeOrganizer = mock(IDisplayAreaOrganizer.class);
@@ -639,10 +644,11 @@ public class DisplayContentTests extends WindowTestsBase {
ws.matchesDisplayAreaBounds());
assertTrue("IME shouldn't be attached to app",
- dc.computeImeParent() != dc.getImeTarget(IME_TARGET_LAYERING).getWindow()
- .mActivityRecord.getSurfaceControl());
+ dc.computeImeParent().getSurfaceControl() != dc.getImeTarget(
+ IME_TARGET_LAYERING).getWindow().mActivityRecord.getSurfaceControl());
assertEquals("IME should be attached to display",
- dc.getImeContainer().getParent().getSurfaceControl(), dc.computeImeParent());
+ dc.getImeContainer().getParent().getSurfaceControl(),
+ dc.computeImeParent().getSurfaceControl());
}
private WindowState[] createNotDrawnWindowsOn(DisplayContent displayContent, int... types) {
@@ -1191,8 +1197,9 @@ public class DisplayContentTests extends WindowTestsBase {
final DisplayContent dc = createNewDisplay();
dc.setImeLayeringTarget(createWindow(null, TYPE_BASE_APPLICATION, "app"));
dc.setImeInputTarget(dc.getImeTarget(IME_TARGET_LAYERING).getWindow());
- assertEquals(dc.getImeTarget(IME_TARGET_LAYERING).getWindow()
- .mActivityRecord.getSurfaceControl(), dc.computeImeParent());
+ assertEquals(dc.getImeTarget(
+ IME_TARGET_LAYERING).getWindow().mActivityRecord.getSurfaceControl(),
+ dc.computeImeParent().getSurfaceControl());
}
@Test
@@ -1202,7 +1209,8 @@ public class DisplayContentTests extends WindowTestsBase {
dc.getImeTarget(IME_TARGET_LAYERING).getWindow().setWindowingMode(
WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
dc.setImeInputTarget(dc.getImeTarget(IME_TARGET_LAYERING).getWindow());
- assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
+ assertEquals(dc.getImeContainer().getParentSurfaceControl(),
+ dc.computeImeParent().getSurfaceControl());
}
@SetupWindows(addWindows = W_ACTIVITY)
@@ -1213,7 +1221,7 @@ public class DisplayContentTests extends WindowTestsBase {
mDisplayContent.setImeLayeringTarget(mAppWindow);
// The surface parent of IME should be the display instead of app window.
assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(),
- mDisplayContent.computeImeParent());
+ mDisplayContent.computeImeParent().getSurfaceControl());
}
@Test
@@ -1221,7 +1229,8 @@ public class DisplayContentTests extends WindowTestsBase {
final DisplayContent dc = createNewDisplay();
dc.setImeLayeringTarget(createWindow(null, TYPE_STATUS_BAR, "statusBar"));
dc.setImeInputTarget(dc.getImeTarget(IME_TARGET_LAYERING).getWindow());
- assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
+ assertEquals(dc.getImeContainer().getParentSurfaceControl(),
+ dc.computeImeParent().getSurfaceControl());
}
@SetupWindows(addWindows = W_ACTIVITY)
@@ -1232,7 +1241,8 @@ public class DisplayContentTests extends WindowTestsBase {
doReturn(true).when(mDisplayContent).shouldImeAttachedToApp();
mDisplayContent.setImeLayeringTarget(app1);
mDisplayContent.setImeInputTarget(app1);
- assertEquals(app1.mActivityRecord.getSurfaceControl(), mDisplayContent.computeImeParent());
+ assertEquals(app1.mActivityRecord.getSurfaceControl(),
+ mDisplayContent.computeImeParent().getSurfaceControl());
mDisplayContent.setImeLayeringTarget(app2);
// Expect null means no change IME parent when the IME layering target not yet
// request IME to be the input target.
@@ -1250,7 +1260,7 @@ public class DisplayContentTests extends WindowTestsBase {
mDisplayContent.setImeInputTarget(app);
assertFalse(mDisplayContent.shouldImeAttachedToApp());
assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(),
- mDisplayContent.computeImeParent());
+ mDisplayContent.computeImeParent().getSurfaceControl());
}
@Test
@@ -1275,7 +1285,8 @@ public class DisplayContentTests extends WindowTestsBase {
assertEquals(dc.getImeTarget(IME_TARGET_LAYERING), dc.getImeInputTarget());
// The ImeParent should be the display.
- assertEquals(dc.getImeContainer().getParent().getSurfaceControl(), dc.computeImeParent());
+ assertEquals(dc.getImeContainer().getParent().getSurfaceControl(),
+ dc.computeImeParent().getSurfaceControl());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index fd959b950e16..65a6a69fc45e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -884,7 +884,7 @@ public class TaskFragmentTest extends WindowTestsBase {
// The ImeParent should be the display.
assertEquals(mDisplayContent.getImeContainer().getParent().getSurfaceControl(),
- mDisplayContent.computeImeParent());
+ mDisplayContent.computeImeParent().getSurfaceControl());
}
@Test