diff options
Diffstat (limited to 'libs')
4 files changed, 126 insertions, 104 deletions
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 ce1139b4264d..53aa61477483 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 @@ -59,42 +59,39 @@ public final class PipBoundsState { private final @NonNull Rect mExpandedBounds = new Rect(); private final @NonNull Rect mNormalMovementBounds = new Rect(); private final @NonNull Rect mExpandedMovementBounds = new Rect(); - private final Context mContext; + private final @NonNull Context mContext; private float mAspectRatio; private int mStashedState = STASH_TYPE_NONE; private int mStashOffset; - private PipReentryState mPipReentryState; - private ComponentName mLastPipComponentName; - private final DisplayInfo mDisplayInfo = new DisplayInfo(); - private final DisplayLayout mDisplayLayout = new DisplayLayout(); + private @Nullable PipReentryState mPipReentryState; + private @Nullable ComponentName mLastPipComponentName; + private final @NonNull DisplayInfo mDisplayInfo = new DisplayInfo(); + private final @NonNull DisplayLayout mDisplayLayout = new DisplayLayout(); /** The current minimum edge size of PIP. */ private int mMinEdgeSize; /** The preferred minimum (and default) size specified by apps. */ - private Size mOverrideMinSize; - private final @NonNull AnimatingBoundsState mAnimatingBoundsState = new AnimatingBoundsState(); + private @Nullable Size mOverrideMinSize; + private final @NonNull MotionBoundsState mMotionBoundsState = new MotionBoundsState(); private boolean mIsImeShowing; private int mImeHeight; private boolean mIsShelfShowing; private int mShelfHeight; - private Runnable mOnMinimalSizeChangeCallback; - private BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback; + private @Nullable Runnable mOnMinimalSizeChangeCallback; + private @Nullable BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback; - public PipBoundsState(Context context) { + public PipBoundsState(@NonNull Context context) { mContext = context; reloadResources(); } - /** - * Reloads the resources. - */ + /** Reloads the resources. */ public void onConfigurationChanged() { reloadResources(); } private void reloadResources() { - mStashOffset = mContext.getResources() - .getDimensionPixelSize(R.dimen.pip_stash_offset); + mStashOffset = mContext.getResources().getDimensionPixelSize(R.dimen.pip_stash_offset); } /** Set the current PIP bounds. */ @@ -102,12 +99,14 @@ public final class PipBoundsState { mBounds.set(bounds); } + /** Get the current PIP bounds. */ @NonNull public Rect getBounds() { return new Rect(mBounds); } /** Returns the current movement bounds. */ + @NonNull public Rect getMovementBounds() { return mMovementBounds; } @@ -135,28 +134,28 @@ public final class PipBoundsState { } /** Set the normal movement bounds. */ - public void setNormalMovementBounds(Rect bounds) { + public void setNormalMovementBounds(@NonNull Rect bounds) { mNormalMovementBounds.set(bounds); } /** Returns the normal movement bounds. */ + @NonNull public Rect getNormalMovementBounds() { return mNormalMovementBounds; } /** Set the expanded movement bounds. */ - public void setExpandedMovementBounds(Rect bounds) { + public void setExpandedMovementBounds(@NonNull Rect bounds) { mExpandedMovementBounds.set(bounds); } /** Returns the expanded movement bounds. */ + @NonNull public Rect getExpandedMovementBounds() { return mExpandedMovementBounds; } - /** - * Dictate where PiP currently should be stashed, if at all. - */ + /** Dictate where PiP currently should be stashed, if at all. */ public void setStashed(@StashType int stashedState) { mStashedState = stashedState; } @@ -169,50 +168,39 @@ public final class PipBoundsState { return mStashedState; } - /** - * Whether PiP is stashed or not. - */ + /** Whether PiP is stashed or not. */ public boolean isStashed() { return mStashedState != STASH_TYPE_NONE; } - /** - * Returns the offset from the edge of the screen for PiP stash. - */ + /** Returns the offset from the edge of the screen for PiP stash. */ public int getStashOffset() { return mStashOffset; } + /** Set the PIP aspect ratio. */ public void setAspectRatio(float aspectRatio) { mAspectRatio = aspectRatio; } + /** Get the PIP aspect ratio. */ public float getAspectRatio() { return mAspectRatio; } - /** - * Save the reentry state to restore to when re-entering PIP mode. - * - * TODO(b/169373982): consider refactoring this so that this class alone can use mBounds and - * calculate the snap fraction to save for re-entry. - */ + /** Save the reentry state to restore to when re-entering PIP mode. */ public void saveReentryState(@NonNull Rect bounds, float fraction) { mPipReentryState = new PipReentryState(new Size(bounds.width(), bounds.height()), fraction); } - /** - * Returns the saved reentry state. - */ + /** Returns the saved reentry state. */ @Nullable public PipReentryState getReentryState() { return mPipReentryState; } - /** - * Set the last {@link ComponentName} to enter PIP mode. - */ - public void setLastPipComponentName(ComponentName lastPipComponentName) { + /** Set the last {@link ComponentName} to enter PIP mode. */ + public void setLastPipComponentName(@Nullable ComponentName lastPipComponentName) { final boolean changed = !Objects.equals(mLastPipComponentName, lastPipComponentName); mLastPipComponentName = lastPipComponentName; if (changed) { @@ -220,41 +208,40 @@ public final class PipBoundsState { } } + /** Get the last PIP component name, if any. */ + @Nullable public ComponentName getLastPipComponentName() { return mLastPipComponentName; } + /** Get the current display info. */ @NonNull public DisplayInfo getDisplayInfo() { return mDisplayInfo; } - /** - * Update the display info. - */ + /** Update the display info. */ public void setDisplayInfo(@NonNull DisplayInfo displayInfo) { mDisplayInfo.copyFrom(displayInfo); } + /** Set the rotation of the display. */ public void setDisplayRotation(int rotation) { mDisplayInfo.rotation = rotation; } - /** - * Returns the display's bound. - */ + /** Returns the display's bounds. */ @NonNull public Rect getDisplayBounds() { return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); } - /** - * Update the display layout. - */ + /** Update the display layout. */ public void setDisplayLayout(@NonNull DisplayLayout displayLayout) { mDisplayLayout.set(displayLayout); } + /** Get the display layout. */ @NonNull public DisplayLayout getDisplayLayout() { return mDisplayLayout; @@ -275,10 +262,8 @@ public final class PipBoundsState { return mMinEdgeSize; } - /** - * Sets the preferred size of PIP as specified by the activity in PIP mode. - */ - public void setOverrideMinSize(Size overrideMinSize) { + /** Sets the preferred size of PIP as specified by the activity in PIP mode. */ + public void setOverrideMinSize(@Nullable Size overrideMinSize) { final boolean changed = !Objects.equals(overrideMinSize, mOverrideMinSize); mOverrideMinSize = overrideMinSize; if (changed && mOnMinimalSizeChangeCallback != null) { @@ -287,6 +272,7 @@ public final class PipBoundsState { } /** Returns the preferred minimal size specified by the activity in PIP. */ + @Nullable public Size getOverrideMinSize() { return mOverrideMinSize; } @@ -297,8 +283,10 @@ public final class PipBoundsState { return Math.min(mOverrideMinSize.getWidth(), mOverrideMinSize.getHeight()); } - public AnimatingBoundsState getAnimatingBoundsState() { - return mAnimatingBoundsState; + /** Get the state of the bounds in motion. */ + @NonNull + public MotionBoundsState getMotionBoundsState() { + return mMotionBoundsState; } /** Set whether the IME is currently showing and its height. */ @@ -344,41 +332,41 @@ public final class PipBoundsState { /** * Registers a callback when the minimal size of PIP that is set by the app changes. */ - public void setOnMinimalSizeChangeCallback(Runnable onMinimalSizeChangeCallback) { + public void setOnMinimalSizeChangeCallback(@Nullable Runnable onMinimalSizeChangeCallback) { mOnMinimalSizeChangeCallback = onMinimalSizeChangeCallback; } /** Set a callback to be notified when the shelf visibility changes. */ public void setOnShelfVisibilityChangeCallback( - BiConsumer<Boolean, Integer> onShelfVisibilityChangeCallback) { + @Nullable 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. */ - private final Rect mTemporaryBounds = new Rect(); + /** Source of truth for the current bounds of PIP that may be in motion. */ + public static class MotionBoundsState { + /** The bounds used when PIP is in motion (e.g. during a drag or animation) */ + private final @NonNull Rect mBoundsInMotion = new Rect(); /** The destination bounds to which PIP is animating. */ - private final Rect mAnimatingToBounds = new Rect(); + private final @NonNull Rect mAnimatingToBounds = new Rect(); /** Whether PIP is being dragged or animated (e.g. resizing, in fling, etc). */ - public boolean isAnimating() { - return !mTemporaryBounds.isEmpty(); + public boolean isInMotion() { + return !mBoundsInMotion.isEmpty(); } /** Set the temporary bounds used to represent the drag or animation bounds of PIP. */ - public void setTemporaryBounds(Rect bounds) { - mTemporaryBounds.set(bounds); + public void setBoundsInMotion(@NonNull Rect bounds) { + mBoundsInMotion.set(bounds); } /** Set the bounds to which PIP is animating. */ - public void setAnimatingToBounds(Rect bounds) { + public void setAnimatingToBounds(@NonNull Rect bounds) { mAnimatingToBounds.set(bounds); } - /** Called when all ongoing dragging and animation operations have ended. */ + /** Called when all ongoing motion operations have ended. */ public void onAllAnimationsEnded() { - mTemporaryBounds.setEmpty(); + mBoundsInMotion.setEmpty(); } /** Called when an ongoing physics animation has ended. */ @@ -386,20 +374,22 @@ public final class PipBoundsState { mAnimatingToBounds.setEmpty(); } - /** Returns the temporary animation bounds. */ - public Rect getTemporaryBounds() { - return mTemporaryBounds; + /** Returns the motion bounds. */ + @NonNull + public Rect getBoundsInMotion() { + return mBoundsInMotion; } /** Returns the destination bounds to which PIP is currently animating. */ + @NonNull public Rect getAnimatingToBounds() { return mAnimatingToBounds; } void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; - pw.println(prefix + AnimatingBoundsState.class.getSimpleName()); - pw.println(innerPrefix + "mTemporaryBounds=" + mTemporaryBounds); + pw.println(prefix + MotionBoundsState.class.getSimpleName()); + pw.println(innerPrefix + "mBoundsInMotion=" + mBoundsInMotion); pw.println(innerPrefix + "mAnimatingToBounds=" + mAnimatingToBounds); } } @@ -432,9 +422,7 @@ public final class PipBoundsState { } } - /** - * Dumps internal state. - */ + /** Dumps internal state. */ public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); @@ -461,6 +449,6 @@ public final class PipBoundsState { } else { mPipReentryState.dump(pw, innerPrefix); } - mAnimatingBoundsState.dump(pw, innerPrefix); + mMotionBoundsState.dump(pw, innerPrefix); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index 8fa944886905..903f7d773896 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -90,7 +90,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, }); /** - * PhysicsAnimator instance for animating {@link PipBoundsState#getAnimatingBoundsState()} + * PhysicsAnimator instance for animating {@link PipBoundsState#getMotionBoundsState()} * using physics animations. */ private final PhysicsAnimator<Rect> mTemporaryBoundsPhysicsAnimator; @@ -98,7 +98,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private MagnetizedObject<Rect> mMagnetizedPip; /** - * Update listener that resizes the PIP to {@link PipBoundsState#getAnimatingBoundsState()}. + * Update listener that resizes the PIP to {@link PipBoundsState#getMotionBoundsState()}. */ private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener; @@ -172,14 +172,14 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mFloatingContentCoordinator = floatingContentCoordinator; mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback); mTemporaryBoundsPhysicsAnimator = PhysicsAnimator.getInstance( - mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds()); + mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler( mSfAnimationHandlerThreadLocal.get()); mResizePipUpdateListener = (target, values) -> { - if (mPipBoundsState.getAnimatingBoundsState().isAnimating()) { + if (mPipBoundsState.getMotionBoundsState().isInMotion()) { mPipTaskOrganizer.scheduleUserResizePip(getBounds(), - mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds(), null); + mPipBoundsState.getMotionBoundsState().getBoundsInMotion(), null); } }; } @@ -187,8 +187,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, @NonNull @Override public Rect getFloatingBoundsOnScreen() { - return !mPipBoundsState.getAnimatingBoundsState().getAnimatingToBounds().isEmpty() - ? mPipBoundsState.getAnimatingBoundsState().getAnimatingToBounds() : getBounds(); + return !mPipBoundsState.getMotionBoundsState().getAnimatingToBounds().isEmpty() + ? mPipBoundsState.getMotionBoundsState().getAnimatingToBounds() : getBounds(); } @NonNull @@ -207,7 +207,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, */ void synchronizePinnedStackBounds() { cancelPhysicsAnimation(); - mPipBoundsState.getAnimatingBoundsState().onAllAnimationsEnded(); + mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded(); if (mPipTaskOrganizer.isInPip()) { mFloatingContentCoordinator.onContentMoved(this); @@ -242,7 +242,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, resizePipUnchecked(toBounds); mPipBoundsState.setBounds(toBounds); } else { - mPipBoundsState.getAnimatingBoundsState().setTemporaryBounds(toBounds); + mPipBoundsState.getMotionBoundsState().setBoundsInMotion(toBounds); mPipTaskOrganizer.scheduleUserResizePip(getBounds(), toBounds, (Rect newBounds) -> { mMainHandler.post(() -> { @@ -278,8 +278,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, // If we're already in the dismiss target area, then there won't be a move to set the // temporary bounds, so just initialize it to the current bounds. - if (!mPipBoundsState.getAnimatingBoundsState().isAnimating()) { - mPipBoundsState.getAnimatingBoundsState().setTemporaryBounds(getBounds()); + if (!mPipBoundsState.getMotionBoundsState().isInMotion()) { + mPipBoundsState.getMotionBoundsState().setBoundsInMotion(getBounds()); } mTemporaryBoundsPhysicsAnimator .spring(FloatProperties.RECT_X, destinationX, velX, mSpringConfig) @@ -396,7 +396,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, final float xEndValue = velocityX < 0 ? leftEdge : rightEdge; - final int startValueY = mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds().top; + final int startValueY = mPipBoundsState.getMotionBoundsState().getBoundsInMotion().top; final float estimatedFlingYEndValue = PhysicsAnimator.estimateFlingEndValue(startValueY, velocityY, mFlingConfigY); @@ -411,7 +411,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, void animateToBounds(Rect bounds, PhysicsAnimator.SpringConfig springConfig) { if (!mTemporaryBoundsPhysicsAnimator.isRunning()) { // Animate from the current bounds if we're not already animating. - mPipBoundsState.getAnimatingBoundsState().setTemporaryBounds(getBounds()); + mPipBoundsState.getMotionBoundsState().setBoundsInMotion(getBounds()); } mTemporaryBoundsPhysicsAnimator @@ -492,7 +492,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, */ private void cancelPhysicsAnimation() { mTemporaryBoundsPhysicsAnimator.cancel(); - mPipBoundsState.getAnimatingBoundsState().onPhysicsAnimationEnded(); + mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); mSpringingToTouch = false; } @@ -565,17 +565,17 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, if (!mDismissalPending && !mSpringingToTouch && !mMagnetizedPip.getObjectStuckToTarget()) { - // All animations (including dragging) have actually finished. + // All motion operations have actually finished. mPipBoundsState.setBounds( - mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds()); - mPipBoundsState.getAnimatingBoundsState().onAllAnimationsEnded(); + mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); + mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded(); if (!mDismissalPending) { // do not schedule resize if PiP is dismissing, which may cause app re-open to // mBounds instead of it's normal bounds. mPipTaskOrganizer.scheduleFinishResizePip(getBounds()); } } - mPipBoundsState.getAnimatingBoundsState().onPhysicsAnimationEnded(); + mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); mSpringingToTouch = false; mDismissalPending = false; } @@ -586,7 +586,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, * {@link FloatingContentCoordinator.FloatingContent#getFloatingBoundsOnScreen()}. */ private void setAnimatingToBounds(Rect bounds) { - mPipBoundsState.getAnimatingBoundsState().setAnimatingToBounds(bounds); + mPipBoundsState.getMotionBoundsState().setAnimatingToBounds(bounds); mFloatingContentCoordinator.onContentMoved(this); } @@ -625,7 +625,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, MagnetizedObject<Rect> getMagnetizedPip() { if (mMagnetizedPip == null) { mMagnetizedPip = new MagnetizedObject<Rect>( - mContext, mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds(), + mContext, mPipBoundsState.getMotionBoundsState().getBoundsInMotion(), FloatProperties.RECT_X, FloatProperties.RECT_Y) { @Override public float getWidth(@NonNull Rect animatedPipBounds) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index 48fa2115305d..a78c4ecdb39f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -706,7 +706,7 @@ public class PipTouchHandler { return; } - Rect bounds = getPossiblyAnimatingBounds(); + Rect bounds = getPossiblyMotionBounds(); mDelta.set(0f, 0f); mStartPosition.set(bounds.left, bounds.top); mMovementWithinDismiss = touchState.getDownTouchPosition().y @@ -745,7 +745,7 @@ public class PipTouchHandler { mDelta.x += left - lastX; mDelta.y += top - lastY; - mTmpBounds.set(getPossiblyAnimatingBounds()); + mTmpBounds.set(getPossiblyMotionBounds()); mTmpBounds.offsetTo((int) left, (int) top); mMotionHelper.movePip(mTmpBounds, true /* isDragging */); @@ -895,12 +895,12 @@ public class PipTouchHandler { } /** - * Returns the PIP bounds if we're not animating, or the current, temporary animating bounds - * otherwise. + * Returns the PIP bounds if we're not in the middle of a motion operation, or the current, + * temporary motion bounds otherwise. */ - Rect getPossiblyAnimatingBounds() { - return mPipBoundsState.getAnimatingBoundsState().isAnimating() - ? mPipBoundsState.getAnimatingBoundsState().getTemporaryBounds() + Rect getPossiblyMotionBounds() { + return mPipBoundsState.getMotionBoundsState().isInMotion() + ? mPipBoundsState.getMotionBoundsState().getBoundsInMotion() : mPipBoundsState.getBounds(); } 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 59e10c189046..4bcca06b592f 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 @@ -135,4 +135,38 @@ public class PipBoundsStateTest extends ShellTestCase { verify(callback, never()).accept(true, 100); } + + @Test + public void testSetOverrideMinSize_changed_callbackInvoked() { + final Runnable callback = mock(Runnable.class); + mPipBoundsState.setOverrideMinSize(new Size(5, 5)); + mPipBoundsState.setOnMinimalSizeChangeCallback(callback); + + mPipBoundsState.setOverrideMinSize(new Size(10, 10)); + + verify(callback).run(); + } + + @Test + public void testSetOverrideMinSize_notChanged_callbackNotInvoked() { + final Runnable callback = mock(Runnable.class); + mPipBoundsState.setOverrideMinSize(new Size(5, 5)); + mPipBoundsState.setOnMinimalSizeChangeCallback(callback); + + mPipBoundsState.setOverrideMinSize(new Size(5, 5)); + + verify(callback, never()).run(); + } + + @Test + public void testGetOverrideMinEdgeSize() { + mPipBoundsState.setOverrideMinSize(null); + assertEquals(0, mPipBoundsState.getOverrideMinEdgeSize()); + + mPipBoundsState.setOverrideMinSize(new Size(5, 10)); + assertEquals(5, mPipBoundsState.getOverrideMinEdgeSize()); + + mPipBoundsState.setOverrideMinSize(new Size(15, 10)); + assertEquals(10, mPipBoundsState.getOverrideMinEdgeSize()); + } } |