Move IME & shelf visibility/height into PipBoundsState
Bug: 169373982
Test: com.android.wm.shell.pip
Change-Id: I411d857c57e2dc593c3506318f5ce1ab6d625b08
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
index 16c0566..ca16cfc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
@@ -59,11 +59,6 @@
private int mDefaultMinSize;
private Point mScreenEdgeInsets;
- private boolean mIsImeShowing;
- private int mImeHeight;
- private boolean mIsShelfShowing;
- private int mShelfHeight;
-
public PipBoundsHandler(Context context, @NonNull PipBoundsState pipBoundsState) {
mPipBoundsState = pipBoundsState;
mSnapAlgorithm = new PipSnapAlgorithm(context);
@@ -101,29 +96,6 @@
}
/**
- * Sets both shelf visibility and its height if applicable.
- * @return {@code true} if the internal shelf state is changed, {@code false} otherwise.
- */
- public boolean setShelfHeight(boolean shelfVisible, int shelfHeight) {
- final boolean shelfShowing = shelfVisible && shelfHeight > 0;
- if (shelfShowing == mIsShelfShowing && shelfHeight == mShelfHeight) {
- return false;
- }
-
- mIsShelfShowing = shelfVisible;
- mShelfHeight = shelfHeight;
- return true;
- }
-
- /**
- * Responds to IPinnedStackListener on IME visibility change.
- */
- public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
- mIsImeShowing = imeVisible;
- mImeHeight = imeHeight;
- }
-
- /**
* Responds to IPinnedStackListener on movement bounds change.
* Note that both inset and normal bounds will be calculated here rather than in the caller.
*/
@@ -360,8 +332,10 @@
mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
}
Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(),
- insetBounds, 0, Math.max(mIsImeShowing ? mImeHeight : 0,
- mIsShelfShowing ? mShelfHeight : 0), defaultBounds);
+ insetBounds, 0, Math.max(
+ mPipBoundsState.isImeShowing() ? mPipBoundsState.getImeHeight() : 0,
+ mPipBoundsState.isShelfShowing()
+ ? mPipBoundsState.getShelfHeight() : 0), defaultBounds);
}
return defaultBounds;
}
@@ -396,7 +370,8 @@
// Apply the movement bounds adjustments based on the current state.
mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
- (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
+ (adjustForIme && mPipBoundsState.isImeShowing())
+ ? mPipBoundsState.getImeHeight() : 0);
return movementBounds;
}
@@ -437,10 +412,6 @@
pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio);
pw.println(innerPrefix + "mMaxAspectRatio=" + mMaxAspectRatio);
pw.println(innerPrefix + "mDefaultStackGravity=" + mDefaultStackGravity);
- pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
- pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
- pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing);
- pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
pw.println(innerPrefix + "mSnapAlgorithm" + mSnapAlgorithm);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index 8d229d3..78f7e25 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -33,6 +33,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
+import java.util.function.BiConsumer;
/**
* Singleton source of truth for the current state of PIP bounds.
@@ -66,8 +67,13 @@
/** The preferred minimum (and default) size specified by apps. */
private Size mOverrideMinSize;
private final @NonNull AnimatingBoundsState mAnimatingBoundsState = new AnimatingBoundsState();
+ private boolean mIsImeShowing;
+ private int mImeHeight;
+ private boolean mIsShelfShowing;
+ private int mShelfHeight;
private Runnable mOnMinimalSizeChangeCallback;
+ private BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback;
public PipBoundsState(Context context) {
mContext = context;
@@ -245,6 +251,46 @@
return mAnimatingBoundsState;
}
+ /** Set whether the IME is currently showing and its height. */
+ public void setImeVisibility(boolean imeShowing, int imeHeight) {
+ mIsImeShowing = imeShowing;
+ mImeHeight = imeHeight;
+ }
+
+ /** Returns whether the IME is currently showing. */
+ public boolean isImeShowing() {
+ return mIsImeShowing;
+ }
+
+ /** Returns the IME height. */
+ public int getImeHeight() {
+ return mImeHeight;
+ }
+
+ /** Set whether the shelf is showing and its height. */
+ public void setShelfVisibility(boolean showing, int height) {
+ final boolean shelfShowing = showing && height > 0;
+ if (shelfShowing == mIsShelfShowing && height == mShelfHeight) {
+ return;
+ }
+
+ mIsShelfShowing = showing;
+ mShelfHeight = height;
+ if (mOnShelfVisibilityChangeCallback != null) {
+ mOnShelfVisibilityChangeCallback.accept(mIsShelfShowing, mShelfHeight);
+ }
+ }
+
+ /** Returns whether the shelf is currently showing. */
+ public boolean isShelfShowing() {
+ return mIsShelfShowing;
+ }
+
+ /** Returns the shelf height. */
+ public int getShelfHeight() {
+ return mShelfHeight;
+ }
+
/**
* Registers a callback when the minimal size of PIP that is set by the app changes.
*/
@@ -252,6 +298,12 @@
mOnMinimalSizeChangeCallback = onMinimalSizeChangeCallback;
}
+ /** Set a callback to be notified when the shelf visibility changes. */
+ public void setOnShelfVisibilityChangeCallback(
+ BiConsumer<Boolean, Integer> onShelfVisibilityChangeCallback) {
+ mOnShelfVisibilityChangeCallback = onShelfVisibilityChangeCallback;
+ }
+
/** Source of truth for the current animation bounds of PIP. */
public static class AnimatingBoundsState {
/** The bounds used when PIP is being dragged or animated. */
@@ -345,6 +397,10 @@
pw.println(innerPrefix + "mStashOffset=" + mStashOffset);
pw.println(innerPrefix + "mMinEdgeSize=" + mMinEdgeSize);
pw.println(innerPrefix + "mOverrideMinSize=" + mOverrideMinSize);
+ pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
+ pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
+ pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing);
+ pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
if (mPipReentryState == null) {
pw.println(innerPrefix + "mPipReentryState=null");
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index c792645..5b54966 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -125,8 +125,8 @@
// not during the fixed rotation. In fixed rotation case, app is about to enter PiP
// and we need the offsets preserved to calculate the destination bounds.
if (!mIsInFixedRotation) {
- mPipBoundsHandler.setShelfHeight(false, 0);
- mPipBoundsHandler.onImeVisibilityChanged(false, 0);
+ mPipBoundsState.setShelfVisibility(false /* showing */, 0 /* height */);
+ mPipBoundsState.setImeVisibility(false /* showing */, 0 /* height */);
mTouchHandler.onShelfVisibilityChanged(false, 0);
mTouchHandler.onImeVisibilityChanged(false, 0);
}
@@ -168,7 +168,7 @@
@Override
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
mMainExecutor.execute(() -> {
- mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+ mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
});
}
@@ -247,6 +247,12 @@
mPipBoundsState = pipBoundsState;
mPipTaskOrganizer = pipTaskOrganizer;
mMainExecutor = mainExecutor;
+ mMediaController = pipMediaController;
+ mMenuController = pipMenuActivityController;
+ mTouchHandler = pipTouchHandler;
+ mAppOpsListener = pipAppOpsListener;
+ mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
+ INPUT_CONSUMER_PIP);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> {
final DisplayInfo newDisplayInfo = new DisplayInfo();
@@ -263,17 +269,17 @@
false /* fromImeAdjustment */, false /* fromShelfAdjustment */,
null /* wct */);
});
- mMediaController = pipMediaController;
- mMenuController = pipMenuActivityController;
- mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
- INPUT_CONSUMER_PIP);
- mTouchHandler = pipTouchHandler;
+ mPipBoundsState.setOnShelfVisibilityChangeCallback((isShowing, height) -> {
+ mTouchHandler.onShelfVisibilityChanged(isShowing, height);
+ updateMovementBounds(mPipBoundsState.getBounds(),
+ false /* fromRotation */, false /* fromImeAdjustment */,
+ true /* fromShelfAdjustment */, null /* windowContainerTransaction */);
+ });
if (mTouchHandler != null) {
// Register the listener for input consumer touch events. Only for Phone
mPipInputConsumer.setInputListener(mTouchHandler::handleTouchEvent);
mPipInputConsumer.setRegistrationListener(mTouchHandler::onRegistrationChanged);
}
- mAppOpsListener = pipAppOpsListener;
displayController.addDisplayChangingController(mRotationController);
displayController.addDisplayWindowListener(mFixedRotationListener);
@@ -413,13 +419,7 @@
private void setShelfHeightLocked(boolean visible, int height) {
final int shelfHeight = visible ? height : 0;
- final boolean changed = mPipBoundsHandler.setShelfHeight(visible, shelfHeight);
- if (changed) {
- mTouchHandler.onShelfVisibilityChanged(visible, shelfHeight);
- updateMovementBounds(mPipBoundsState.getBounds(),
- false /* fromRotation */, false /* fromImeAdjustment */,
- true /* fromShelfAdjustment */, null /* windowContainerTransaction */);
- }
+ mPipBoundsState.setShelfVisibility(visible, shelfHeight);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
index 402d79c..fd055d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
@@ -184,7 +184,7 @@
@Override
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
mHandler.post(() -> {
- mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+ mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
if (mState == STATE_PIP) {
if (mImeVisible != imeVisible) {
if (imeVisible) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
index 440e23c..ba60d3d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
@@ -242,7 +242,7 @@
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect oldPosition = mPipBoundsHandler.getEntryDestinationBounds();
- mPipBoundsHandler.setShelfHeight(true, shelfHeight);
+ mPipBoundsState.setShelfVisibility(true, shelfHeight);
final Rect newPosition = mPipBoundsHandler.getEntryDestinationBounds();
oldPosition.offset(0, -shelfHeight);
@@ -255,7 +255,7 @@
mPipBoundsState.setAspectRatio(DEFAULT_ASPECT_RATIO);
final Rect oldPosition = mPipBoundsHandler.getEntryDestinationBounds();
- mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight);
+ mPipBoundsState.setImeVisibility(true, imeHeight);
final Rect newPosition = mPipBoundsHandler.getEntryDestinationBounds();
oldPosition.offset(0, -imeHeight);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
index 5e11de7..59e10c1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
@@ -19,6 +19,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import android.content.ComponentName;
import android.graphics.Rect;
@@ -34,6 +37,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.function.BiConsumer;
+
/**
* Tests for {@link PipBoundsState}.
*/
@@ -109,4 +114,25 @@
assertNull(mPipBoundsState.getReentryState());
}
+
+ @Test
+ public void testSetShelfVisibility_changed_callbackInvoked() {
+ final BiConsumer<Boolean, Integer> callback = mock(BiConsumer.class);
+ mPipBoundsState.setOnShelfVisibilityChangeCallback(callback);
+
+ mPipBoundsState.setShelfVisibility(true, 100);
+
+ verify(callback).accept(true, 100);
+ }
+
+ @Test
+ public void testSetShelfVisibility_notChanged_callbackNotInvoked() {
+ final BiConsumer<Boolean, Integer> callback = mock(BiConsumer.class);
+ mPipBoundsState.setShelfVisibility(true, 100);
+ mPipBoundsState.setOnShelfVisibilityChangeCallback(callback);
+
+ mPipBoundsState.setShelfVisibility(true, 100);
+
+ verify(callback, never()).accept(true, 100);
+ }
}