Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +1 −2 Original line number Original line Diff line number Diff line Loading @@ -129,10 +129,9 @@ public class PipBoundsAlgorithm { : getDefaultBounds(); : getDefaultBounds(); final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; final Rect r = transformBoundsToAspectRatioIfValid(destinationBounds, return transformBoundsToAspectRatioIfValid(destinationBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, useCurrentSize); useCurrentSize); return r; } } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +10 −4 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.util.Size; import android.view.DisplayInfo; import android.view.DisplayInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.TriConsumer; import com.android.wm.shell.R; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout; Loading @@ -33,7 +34,6 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.Objects; import java.util.Objects; import java.util.function.BiConsumer; /** /** * Singleton source of truth for the current state of PIP bounds. * Singleton source of truth for the current state of PIP bounds. Loading Loading @@ -80,7 +80,7 @@ public final class PipBoundsState { private boolean mHasUserResizedPip; private boolean mHasUserResizedPip; private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback; private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback; public PipBoundsState(@NonNull Context context) { public PipBoundsState(@NonNull Context context) { mContext = context; mContext = context; Loading Loading @@ -310,6 +310,11 @@ public final class PipBoundsState { /** Set whether the shelf is showing and its height. */ /** Set whether the shelf is showing and its height. */ public void setShelfVisibility(boolean showing, int height) { public void setShelfVisibility(boolean showing, int height) { setShelfVisibility(showing, height, true); } /** Set whether the shelf is showing and its height. */ public void setShelfVisibility(boolean showing, int height, boolean updateMovementBounds) { final boolean shelfShowing = showing && height > 0; final boolean shelfShowing = showing && height > 0; if (shelfShowing == mIsShelfShowing && height == mShelfHeight) { if (shelfShowing == mIsShelfShowing && height == mShelfHeight) { return; return; Loading @@ -318,7 +323,8 @@ public final class PipBoundsState { mIsShelfShowing = showing; mIsShelfShowing = showing; mShelfHeight = height; mShelfHeight = height; if (mOnShelfVisibilityChangeCallback != null) { if (mOnShelfVisibilityChangeCallback != null) { mOnShelfVisibilityChangeCallback.accept(mIsShelfShowing, mShelfHeight); mOnShelfVisibilityChangeCallback.accept(mIsShelfShowing, mShelfHeight, updateMovementBounds); } } } } Loading Loading @@ -351,7 +357,7 @@ public final class PipBoundsState { /** Set a callback to be notified when the shelf visibility changes. */ /** Set a callback to be notified when the shelf visibility changes. */ public void setOnShelfVisibilityChangeCallback( public void setOnShelfVisibilityChangeCallback( @Nullable BiConsumer<Boolean, Integer> onShelfVisibilityChangeCallback) { @Nullable TriConsumer<Boolean, Integer, Boolean> onShelfVisibilityChangeCallback) { mOnShelfVisibilityChangeCallback = onShelfVisibilityChangeCallback; mOnShelfVisibilityChangeCallback = onShelfVisibilityChangeCallback; } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +22 −14 Original line number Original line Diff line number Diff line Loading @@ -114,14 +114,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac // the bounds for the next orientation using the destination bounds of the animation // the bounds for the next orientation using the destination bounds of the animation // TODO: Technically this should account for movement animation bounds as well // TODO: Technically this should account for movement animation bounds as well Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds(); Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds(); final boolean changed = onDisplayRotationChanged(mContext, final Rect outBounds = new Rect(); mPipBoundsState.getNormalBounds(), currentBounds, mTmpInsetBounds, displayId, final boolean changed = onDisplayRotationChanged(mContext, outBounds, currentBounds, fromRotation, toRotation, t); mTmpInsetBounds, displayId, fromRotation, toRotation, t); if (changed) { if (changed) { // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // movement bounds // movement bounds mTouchHandler.adjustBoundsForRotation(mPipBoundsState.getNormalBounds(), mTouchHandler.adjustBoundsForRotation(outBounds, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), mTmpInsetBounds); mTmpInsetBounds); // The bounds are being applied to a specific snap fraction, so reset any known offsets // The bounds are being applied to a specific snap fraction, so reset any known offsets // for the previous orientation before updating the movement bounds. // for the previous orientation before updating the movement bounds. Loading @@ -129,14 +129,18 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac // not during the fixed rotation. In fixed rotation case, app is about to enter PiP // 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. // and we need the offsets preserved to calculate the destination bounds. if (!mIsInFixedRotation) { if (!mIsInFixedRotation) { mPipBoundsState.setShelfVisibility(false /* showing */, 0 /* height */); // Update the shelf visibility without updating the movement bounds. We're already // updating them below with the |fromRotation| flag set, which is more accurate // than using the |fromShelfAdjustment|. mPipBoundsState.setShelfVisibility(false /* showing */, 0 /* height */, false /* updateMovementBounds */); mPipBoundsState.setImeVisibility(false /* showing */, 0 /* height */); mPipBoundsState.setImeVisibility(false /* showing */, 0 /* height */); mTouchHandler.onShelfVisibilityChanged(false, 0); mTouchHandler.onShelfVisibilityChanged(false, 0); mTouchHandler.onImeVisibilityChanged(false, 0); mTouchHandler.onImeVisibilityChanged(false, 0); } } updateMovementBounds(mPipBoundsState.getNormalBounds(), true /* fromRotation */, updateMovementBounds(outBounds, true /* fromRotation */, false /* fromImeAdjustment */, false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t); false /* fromShelfAdjustment */, t); } } }; }; Loading Loading @@ -248,11 +252,15 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac false /* fromImeAdjustment */, false /* fromShelfAdjustment */, false /* fromImeAdjustment */, false /* fromShelfAdjustment */, null /* wct */); null /* wct */); }); }); mPipBoundsState.setOnShelfVisibilityChangeCallback((isShowing, height) -> { mPipBoundsState.setOnShelfVisibilityChangeCallback( (isShowing, height, updateMovementBounds) -> { mTouchHandler.onShelfVisibilityChanged(isShowing, height); mTouchHandler.onShelfVisibilityChanged(isShowing, height); if (updateMovementBounds) { updateMovementBounds(mPipBoundsState.getBounds(), updateMovementBounds(mPipBoundsState.getBounds(), false /* fromRotation */, false /* fromImeAdjustment */, false /* fromRotation */, false /* fromImeAdjustment */, true /* fromShelfAdjustment */, null /* windowContainerTransaction */); true /* fromShelfAdjustment */, null /* windowContainerTransaction */); } }); }); if (mTouchHandler != null) { if (mTouchHandler != null) { // Register the listener for input consumer touch events. Only for Phone // Register the listener for input consumer touch events. Only for Phone Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java +15 −6 Original line number Original line Diff line number Diff line Loading @@ -31,14 +31,13 @@ import android.util.Size; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import com.android.internal.util.function.TriConsumer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.ShellTestCase; import org.junit.Before; import org.junit.Before; import org.junit.Test; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runner.RunWith; import java.util.function.BiConsumer; /** /** * Tests for {@link PipBoundsState}. * Tests for {@link PipBoundsState}. */ */ Loading Loading @@ -117,23 +116,33 @@ public class PipBoundsStateTest extends ShellTestCase { @Test @Test public void testSetShelfVisibility_changed_callbackInvoked() { public void testSetShelfVisibility_changed_callbackInvoked() { final BiConsumer<Boolean, Integer> callback = mock(BiConsumer.class); final TriConsumer<Boolean, Integer, Boolean> callback = mock(TriConsumer.class); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setShelfVisibility(true, 100); verify(callback).accept(true, 100); verify(callback).accept(true, 100, true); } @Test public void testSetShelfVisibility_changedWithoutUpdateMovBounds_callbackInvoked() { final TriConsumer<Boolean, Integer, Boolean> callback = mock(TriConsumer.class); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setShelfVisibility(true, 100, false); verify(callback).accept(true, 100, false); } } @Test @Test public void testSetShelfVisibility_notChanged_callbackNotInvoked() { public void testSetShelfVisibility_notChanged_callbackNotInvoked() { final BiConsumer<Boolean, Integer> callback = mock(BiConsumer.class); final TriConsumer<Boolean, Integer, Boolean> callback = mock(TriConsumer.class); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setShelfVisibility(true, 100); verify(callback, never()).accept(true, 100); verify(callback, never()).accept(true, 100, true); } } @Test @Test Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +1 −2 Original line number Original line Diff line number Diff line Loading @@ -129,10 +129,9 @@ public class PipBoundsAlgorithm { : getDefaultBounds(); : getDefaultBounds(); final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null; final Rect r = transformBoundsToAspectRatioIfValid(destinationBounds, return transformBoundsToAspectRatioIfValid(destinationBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, useCurrentSize); useCurrentSize); return r; } } /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ /** Returns the current bounds adjusted to the new aspect ratio, if valid. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +10 −4 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.util.Size; import android.view.DisplayInfo; import android.view.DisplayInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.TriConsumer; import com.android.wm.shell.R; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.DisplayLayout; Loading @@ -33,7 +34,6 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.Objects; import java.util.Objects; import java.util.function.BiConsumer; /** /** * Singleton source of truth for the current state of PIP bounds. * Singleton source of truth for the current state of PIP bounds. Loading Loading @@ -80,7 +80,7 @@ public final class PipBoundsState { private boolean mHasUserResizedPip; private boolean mHasUserResizedPip; private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable Runnable mOnMinimalSizeChangeCallback; private @Nullable BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback; private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback; public PipBoundsState(@NonNull Context context) { public PipBoundsState(@NonNull Context context) { mContext = context; mContext = context; Loading Loading @@ -310,6 +310,11 @@ public final class PipBoundsState { /** Set whether the shelf is showing and its height. */ /** Set whether the shelf is showing and its height. */ public void setShelfVisibility(boolean showing, int height) { public void setShelfVisibility(boolean showing, int height) { setShelfVisibility(showing, height, true); } /** Set whether the shelf is showing and its height. */ public void setShelfVisibility(boolean showing, int height, boolean updateMovementBounds) { final boolean shelfShowing = showing && height > 0; final boolean shelfShowing = showing && height > 0; if (shelfShowing == mIsShelfShowing && height == mShelfHeight) { if (shelfShowing == mIsShelfShowing && height == mShelfHeight) { return; return; Loading @@ -318,7 +323,8 @@ public final class PipBoundsState { mIsShelfShowing = showing; mIsShelfShowing = showing; mShelfHeight = height; mShelfHeight = height; if (mOnShelfVisibilityChangeCallback != null) { if (mOnShelfVisibilityChangeCallback != null) { mOnShelfVisibilityChangeCallback.accept(mIsShelfShowing, mShelfHeight); mOnShelfVisibilityChangeCallback.accept(mIsShelfShowing, mShelfHeight, updateMovementBounds); } } } } Loading Loading @@ -351,7 +357,7 @@ public final class PipBoundsState { /** Set a callback to be notified when the shelf visibility changes. */ /** Set a callback to be notified when the shelf visibility changes. */ public void setOnShelfVisibilityChangeCallback( public void setOnShelfVisibilityChangeCallback( @Nullable BiConsumer<Boolean, Integer> onShelfVisibilityChangeCallback) { @Nullable TriConsumer<Boolean, Integer, Boolean> onShelfVisibilityChangeCallback) { mOnShelfVisibilityChangeCallback = onShelfVisibilityChangeCallback; mOnShelfVisibilityChangeCallback = onShelfVisibilityChangeCallback; } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +22 −14 Original line number Original line Diff line number Diff line Loading @@ -114,14 +114,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac // the bounds for the next orientation using the destination bounds of the animation // the bounds for the next orientation using the destination bounds of the animation // TODO: Technically this should account for movement animation bounds as well // TODO: Technically this should account for movement animation bounds as well Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds(); Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds(); final boolean changed = onDisplayRotationChanged(mContext, final Rect outBounds = new Rect(); mPipBoundsState.getNormalBounds(), currentBounds, mTmpInsetBounds, displayId, final boolean changed = onDisplayRotationChanged(mContext, outBounds, currentBounds, fromRotation, toRotation, t); mTmpInsetBounds, displayId, fromRotation, toRotation, t); if (changed) { if (changed) { // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // movement bounds // movement bounds mTouchHandler.adjustBoundsForRotation(mPipBoundsState.getNormalBounds(), mTouchHandler.adjustBoundsForRotation(outBounds, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), mTmpInsetBounds); mTmpInsetBounds); // The bounds are being applied to a specific snap fraction, so reset any known offsets // The bounds are being applied to a specific snap fraction, so reset any known offsets // for the previous orientation before updating the movement bounds. // for the previous orientation before updating the movement bounds. Loading @@ -129,14 +129,18 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac // not during the fixed rotation. In fixed rotation case, app is about to enter PiP // 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. // and we need the offsets preserved to calculate the destination bounds. if (!mIsInFixedRotation) { if (!mIsInFixedRotation) { mPipBoundsState.setShelfVisibility(false /* showing */, 0 /* height */); // Update the shelf visibility without updating the movement bounds. We're already // updating them below with the |fromRotation| flag set, which is more accurate // than using the |fromShelfAdjustment|. mPipBoundsState.setShelfVisibility(false /* showing */, 0 /* height */, false /* updateMovementBounds */); mPipBoundsState.setImeVisibility(false /* showing */, 0 /* height */); mPipBoundsState.setImeVisibility(false /* showing */, 0 /* height */); mTouchHandler.onShelfVisibilityChanged(false, 0); mTouchHandler.onShelfVisibilityChanged(false, 0); mTouchHandler.onImeVisibilityChanged(false, 0); mTouchHandler.onImeVisibilityChanged(false, 0); } } updateMovementBounds(mPipBoundsState.getNormalBounds(), true /* fromRotation */, updateMovementBounds(outBounds, true /* fromRotation */, false /* fromImeAdjustment */, false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t); false /* fromShelfAdjustment */, t); } } }; }; Loading Loading @@ -248,11 +252,15 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac false /* fromImeAdjustment */, false /* fromShelfAdjustment */, false /* fromImeAdjustment */, false /* fromShelfAdjustment */, null /* wct */); null /* wct */); }); }); mPipBoundsState.setOnShelfVisibilityChangeCallback((isShowing, height) -> { mPipBoundsState.setOnShelfVisibilityChangeCallback( (isShowing, height, updateMovementBounds) -> { mTouchHandler.onShelfVisibilityChanged(isShowing, height); mTouchHandler.onShelfVisibilityChanged(isShowing, height); if (updateMovementBounds) { updateMovementBounds(mPipBoundsState.getBounds(), updateMovementBounds(mPipBoundsState.getBounds(), false /* fromRotation */, false /* fromImeAdjustment */, false /* fromRotation */, false /* fromImeAdjustment */, true /* fromShelfAdjustment */, null /* windowContainerTransaction */); true /* fromShelfAdjustment */, null /* windowContainerTransaction */); } }); }); if (mTouchHandler != null) { if (mTouchHandler != null) { // Register the listener for input consumer touch events. Only for Phone // Register the listener for input consumer touch events. Only for Phone Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java +15 −6 Original line number Original line Diff line number Diff line Loading @@ -31,14 +31,13 @@ import android.util.Size; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import com.android.internal.util.function.TriConsumer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.ShellTestCase; import org.junit.Before; import org.junit.Before; import org.junit.Test; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runner.RunWith; import java.util.function.BiConsumer; /** /** * Tests for {@link PipBoundsState}. * Tests for {@link PipBoundsState}. */ */ Loading Loading @@ -117,23 +116,33 @@ public class PipBoundsStateTest extends ShellTestCase { @Test @Test public void testSetShelfVisibility_changed_callbackInvoked() { public void testSetShelfVisibility_changed_callbackInvoked() { final BiConsumer<Boolean, Integer> callback = mock(BiConsumer.class); final TriConsumer<Boolean, Integer, Boolean> callback = mock(TriConsumer.class); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setShelfVisibility(true, 100); verify(callback).accept(true, 100); verify(callback).accept(true, 100, true); } @Test public void testSetShelfVisibility_changedWithoutUpdateMovBounds_callbackInvoked() { final TriConsumer<Boolean, Integer, Boolean> callback = mock(TriConsumer.class); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setShelfVisibility(true, 100, false); verify(callback).accept(true, 100, false); } } @Test @Test public void testSetShelfVisibility_notChanged_callbackNotInvoked() { public void testSetShelfVisibility_notChanged_callbackNotInvoked() { final BiConsumer<Boolean, Integer> callback = mock(BiConsumer.class); final TriConsumer<Boolean, Integer, Boolean> callback = mock(TriConsumer.class); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setOnShelfVisibilityChangeCallback(callback); mPipBoundsState.setShelfVisibility(true, 100); mPipBoundsState.setShelfVisibility(true, 100); verify(callback, never()).accept(true, 100); verify(callback, never()).accept(true, 100, true); } } @Test @Test Loading