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 cb27ad9f58f56..f565724813ebf 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 @@ -159,6 +159,14 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } } + private void dispatchImeControlTargetChanged(int displayId, boolean controlling) { + synchronized (mPositionProcessors) { + for (ImePositionProcessor pp : mPositionProcessors) { + pp.onImeControlTargetChanged(displayId, controlling); + } + } + } + private void dispatchVisibilityChanged(int displayId, boolean isShowing) { synchronized (mPositionProcessors) { for (ImePositionProcessor pp : mPositionProcessors) { @@ -237,42 +245,52 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged protected void insetsControlChanged(InsetsState insetsState, InsetsSourceControl[] activeControls) { insetsChanged(insetsState); + InsetsSourceControl imeSourceControl = null; if (activeControls != null) { for (InsetsSourceControl activeControl : activeControls) { if (activeControl == null) { continue; } if (activeControl.getType() == InsetsState.ITYPE_IME) { - final Point lastSurfacePosition = mImeSourceControl != null - ? mImeSourceControl.getSurfacePosition() : null; - final boolean positionChanged = - !activeControl.getSurfacePosition().equals(lastSurfacePosition); - final boolean leashChanged = - !haveSameLeash(mImeSourceControl, activeControl); - final InsetsSourceControl lastImeControl = mImeSourceControl; - mImeSourceControl = activeControl; - if (mAnimation != null) { - if (positionChanged) { - startAnimation(mImeShowing, true /* forceRestart */); - } - } else { - if (leashChanged) { - applyVisibilityToLeash(); - } - if (!mImeShowing) { - removeImeSurface(); - } - } - if (lastImeControl != null) { - lastImeControl.release(SurfaceControl::release); - } + imeSourceControl = activeControl; } } } + + final boolean hadImeSourceControl = mImeSourceControl != null; + final boolean hasImeSourceControl = imeSourceControl != null; + if (hadImeSourceControl != hasImeSourceControl) { + dispatchImeControlTargetChanged(mDisplayId, hasImeSourceControl); + } + + if (hasImeSourceControl) { + final Point lastSurfacePosition = mImeSourceControl != null + ? mImeSourceControl.getSurfacePosition() : null; + final boolean positionChanged = + !imeSourceControl.getSurfacePosition().equals(lastSurfacePosition); + final boolean leashChanged = + !haveSameLeash(mImeSourceControl, imeSourceControl); + if (mAnimation != null) { + if (positionChanged) { + startAnimation(mImeShowing, true /* forceRestart */); + } + } else { + if (leashChanged) { + applyVisibilityToLeash(imeSourceControl); + } + if (!mImeShowing) { + removeImeSurface(); + } + } + if (mImeSourceControl != null) { + mImeSourceControl.release(SurfaceControl::release); + } + mImeSourceControl = imeSourceControl; + } } - private void applyVisibilityToLeash() { - SurfaceControl leash = mImeSourceControl.getLeash(); + private void applyVisibilityToLeash(InsetsSourceControl imeSourceControl) { + SurfaceControl leash = imeSourceControl.getLeash(); if (leash != null) { SurfaceControl.Transaction t = mTransactionPool.acquire(); if (mImeShowing) { @@ -583,6 +601,15 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged SurfaceControl.Transaction t) { } + /** + * Called when the IME control target changed. So that the processor can restore its + * adjusted layout when the IME insets is not controlling by the current controller anymore. + * + * @param controlling indicates whether the current controller is controlling IME insets. + */ + default void onImeControlTargetChanged(int displayId, boolean controlling) { + } + /** * Called when the IME visibility changed. * diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index e42f511eb3914..5b158d2063bae 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -366,6 +366,7 @@ public final class SplitLayout { private final int mDisplayId; + private boolean mImeShown; private int mYOffsetForIme; private float mDimValue1; private float mDimValue2; @@ -392,6 +393,7 @@ public final class SplitLayout { if (!mInitialized || imeTargetPosition == SPLIT_POSITION_UNDEFINED) return 0; mStartImeTop = showing ? hiddenTop : shownTop; mEndImeTop = showing ? shownTop : hiddenTop; + mImeShown = showing; // Update target dim values mLastDim1 = mDimValue1; @@ -414,7 +416,7 @@ public final class SplitLayout { mSplitWindowManager.setInteractive( !showing || imeTargetPosition == SPLIT_POSITION_UNDEFINED); - return 0; + return needOffset ? IME_ANIMATION_NO_ALPHA : 0; } @Override @@ -432,6 +434,17 @@ public final class SplitLayout { mSplitLayoutHandler.onBoundsChanging(SplitLayout.this); } + @Override + public void onImeControlTargetChanged(int displayId, boolean controlling) { + if (displayId != mDisplayId) return; + // Restore the split layout when wm-shell is not controlling IME insets anymore. + if (!controlling && mImeShown) { + reset(); + mSplitWindowManager.setInteractive(true); + mSplitLayoutHandler.onBoundsChanging(SplitLayout.this); + } + } + private int getTargetYOffset() { final int desireOffset = Math.abs(mEndImeTop - mStartImeTop); // Make sure to keep at least 30% visible for the top split. @@ -461,8 +474,10 @@ public final class SplitLayout { } private void reset() { - mYOffsetForIme = 0; - mDimValue1 = mDimValue2 = 0.0f; + mImeShown = false; + mYOffsetForIme = mLastYOffset = mTargetYOffset = 0; + mDimValue1 = mLastDim1 = mTargetDim1 = 0.0f; + mDimValue2 = mLastDim2 = mTargetDim2 = 0.0f; } /* Adjust bounds with IME offset. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java index 23171bb9575cc..aced072c8c717 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java @@ -91,7 +91,6 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor private boolean mPaused = true; private boolean mPausedTargetAdjusted = false; - private boolean mAdjustedWhileHidden = false; DividerImeController(LegacySplitScreenTaskListener splits, TransactionPool pool, ShellExecutor mainExecutor, TaskOrganizer taskOrganizer) { @@ -123,7 +122,6 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor void reset() { mPaused = true; mPausedTargetAdjusted = false; - mAdjustedWhileHidden = false; mAnimation = null; mAdjusted = mTargetAdjusted = false; mImeWasShown = mTargetShown = false; @@ -140,6 +138,19 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor ? ADJUSTED_NONFOCUS_DIM : 0.f; } + + @Override + public void onImeControlTargetChanged(int displayId, boolean controlling) { + // Restore the split layout when wm-shell is not controlling IME insets anymore. + if (!controlling && mTargetShown) { + mPaused = false; + mTargetAdjusted = mTargetShown = false; + mTargetPrimaryDim = mTargetSecondaryDim = 0.f; + updateImeAdjustState(true /* force */); + startAsyncAnimation(); + } + } + @Override @ImeAnimationFlags public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop, @@ -151,8 +162,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor mShownTop = shownTop; mTargetShown = imeShouldShow; mSecondaryHasFocus = getSecondaryHasFocus(displayId); - final boolean splitIsVisible = !getView().isHidden(); - final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus + final boolean targetAdjusted = imeShouldShow && mSecondaryHasFocus && !imeIsFloating && !getLayout().mDisplayLayout.isLandscape() && !mSplits.mSplitScreenController.isMinimized(); if (mLastAdjustTop < 0) { @@ -176,7 +186,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor } mTargetAdjusted = targetAdjusted; updateDimTargets(); - if (DEBUG) Slog.d(TAG, " ime starting. vis:" + splitIsVisible + " " + dumpState()); + if (DEBUG) Slog.d(TAG, " ime starting. " + dumpState()); if (mAnimation != null || (mImeWasShown && imeShouldShow && mTargetAdjusted != mAdjusted)) { // We need to animate adjustment independently of the IME position, so @@ -184,13 +194,8 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor // different split's editor has gained focus while the IME is still visible. startAsyncAnimation(); } - if (splitIsVisible) { - // If split is hidden, we don't want to trigger any relayouts that would cause the - // divider to show again. - updateImeAdjustState(); - } else { - mAdjustedWhileHidden = true; - } + updateImeAdjustState(); + return (mTargetAdjusted || mAdjusted) ? IME_ANIMATION_NO_ALPHA : 0; } @@ -256,11 +261,6 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor mSplits.mSplitScreenController.setAdjustedForIme(mTargetShown && !mPaused); } - public void updateAdjustForIme() { - updateImeAdjustState(mAdjustedWhileHidden); - mAdjustedWhileHidden = false; - } - @Override public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java index ea2fc1aae2908..80ab166d06499 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java @@ -227,9 +227,6 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays return; } mView.setHidden(showing); - if (!showing) { - mImePositionProcessor.updateAdjustForIme(); - } mIsKeyguardShowing = showing; }