diff options
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 |