From 80a068e144d58f141dff7b7fb41292cc3c919f38 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Thu, 24 Jun 2021 09:15:45 +0000 Subject: [PATCH] Restore split layout when wm-shell no longer controlling IME Add a callback in ImePositionProcessor to notify IME cotnrol target changed. And make sure to restore the split layout when wm-shell is not contorlling IME insets anymore. Fix: 174119991 Test: 1. open IME on the bootom split to adjust split layout with IME 2. focus on direct reply of open passwork keyguard 3. observe the split layout been restored after back to split Change-Id: I5caeeff9406d21e21c8a82c0078cbfae36bd4063 Merged-In: I5caeeff9406d21e21c8a82c0078cbfae36bd4063 --- .../wm/shell/common/DisplayImeController.java | 77 +++++++++++++------ .../wm/shell/common/split/SplitLayout.java | 21 ++++- .../DividerImeController.java | 34 ++++---- .../LegacySplitScreenController.java | 3 - 4 files changed, 87 insertions(+), 48 deletions(-) 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; }