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
This commit is contained in:
Jerry Chang
2021-06-24 09:15:45 +00:00
parent 4260ce4100
commit 80a068e144
4 changed files with 87 additions and 48 deletions

View File

@@ -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.
*

View File

@@ -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. */

View File

@@ -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) {

View File

@@ -227,9 +227,6 @@ public class LegacySplitScreenController implements DisplayController.OnDisplays
return;
}
mView.setHidden(showing);
if (!showing) {
mImePositionProcessor.updateAdjustForIme();
}
mIsKeyguardShowing = showing;
}