Move IME & shelf visibility/height into PipBoundsState

Bug: 169373982
Test: com.android.wm.shell.pip
Change-Id: I411d857c57e2dc593c3506318f5ce1ab6d625b08
This commit is contained in:
jorgegil@google.com
2020-11-09 12:59:27 -08:00
parent a61e9fec04
commit d6349bb46b
6 changed files with 107 additions and 54 deletions

View File

@@ -59,11 +59,6 @@ public class PipBoundsHandler {
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);
@@ -100,29 +95,6 @@ public class PipBoundsHandler {
com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
}
/**
* 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 @@ public class PipBoundsHandler {
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 @@ public class PipBoundsHandler {
// 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 @@ public class PipBoundsHandler {
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);
}
}

View File

@@ -33,6 +33,7 @@ import java.io.PrintWriter;
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 @@ public final class PipBoundsState {
/** 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 @@ public final class PipBoundsState {
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 @@ public final class PipBoundsState {
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 @@ public final class PipBoundsState {
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 {

View File

@@ -125,8 +125,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
// 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 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@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 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
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 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
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 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
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

View File

@@ -184,7 +184,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
@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) {

View File

@@ -242,7 +242,7 @@ public class PipBoundsHandlerTest extends ShellTestCase {
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 @@ public class PipBoundsHandlerTest extends ShellTestCase {
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);

View File

@@ -19,6 +19,9 @@ package com.android.wm.shell.pip;
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.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.function.BiConsumer;
/**
* Tests for {@link PipBoundsState}.
*/
@@ -109,4 +114,25 @@ public class PipBoundsStateTest extends ShellTestCase {
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);
}
}