Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +20 −3 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import com.android.wm.shell.pip2.phone.PhonePipMenuController; import com.android.wm.shell.pip2.phone.PipController; import com.android.wm.shell.pip2.phone.PipMotionHelper; import com.android.wm.shell.pip2.phone.PipScheduler; import com.android.wm.shell.pip2.phone.PipTaskListener; import com.android.wm.shell.pip2.phone.PipTouchHandler; import com.android.wm.shell.pip2.phone.PipTransition; import com.android.wm.shell.pip2.phone.PipTransitionState; Loading Loading @@ -73,12 +74,13 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, PipTouchHandler pipTouchHandler, PipTaskListener pipTaskListener, @NonNull PipScheduler pipScheduler, @NonNull PipTransitionState pipStackListenerController, @NonNull PipUiStateChangeController pipUiStateChangeController) { return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, pipBoundsAlgorithm, pipScheduler, pipStackListenerController, pipUiStateChangeController); pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener, pipScheduler, pipStackListenerController, pipUiStateChangeController); } @WMSingleton Loading Loading @@ -123,9 +125,11 @@ public abstract class Pip2Module { @Provides static PipScheduler providePipScheduler(Context context, PipBoundsState pipBoundsState, PhonePipMenuController pipMenuController, @ShellMainThread ShellExecutor mainExecutor, PipTransitionState pipTransitionState) { return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState); return new PipScheduler(context, pipBoundsState, pipMenuController, mainExecutor, pipTransitionState); } @WMSingleton Loading Loading @@ -190,4 +194,17 @@ public abstract class Pip2Module { PipTransitionState pipTransitionState) { return new PipUiStateChangeController(pipTransitionState); } @WMSingleton @Provides static PipTaskListener providePipTaskListener(Context context, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, PipScheduler pipScheduler, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, @ShellMainThread ShellExecutor mainExecutor) { return new PipTaskListener(context, shellTaskOrganizer, pipTransitionState, pipScheduler, pipBoundsState, pipBoundsAlgorithm, mainExecutor); } } libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java +3 −2 Original line number Diff line number Diff line Loading @@ -134,9 +134,10 @@ public class PipResizeAnimator extends ValueAnimator Rect baseBounds, Rect targetBounds, float degrees) { Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; final float scale = (float) targetBounds.width() / baseBounds.width(); final float scaleX = (float) targetBounds.width() / baseBounds.width(); final float scaleY = (float) targetBounds.height() / baseBounds.height(); transformTensor.setScale(scale, scale); transformTensor.setScale(scaleX, scaleY); transformTensor.postTranslate(targetBounds.left, targetBounds.top); transformTensor.postRotate(degrees, targetBounds.centerX(), targetBounds.centerY()); Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +3 −29 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import kotlin.Unit; import kotlin.jvm.functions.Function0; import java.util.Optional; import java.util.function.Consumer; /** * A helper to animate and manipulate the PiP. Loading Loading @@ -134,18 +133,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig = new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_NO_BOUNCY); @Nullable private Runnable mUpdateMovementBoundsRunnable; private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> { if (mPipBoundsState.getBounds().equals(newBounds)) { return; } mMenuController.updateMenuLayout(newBounds); mPipBoundsState.setBounds(newBounds); maybeUpdateMovementBounds(); }; /** * Whether we're springing to the touch event location (vs. moving it to that position * instantly). We spring-to-touch after PIP is dragged out of the magnetic target, since it was Loading Loading @@ -683,16 +670,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); } void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) { mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; } private void maybeUpdateMovementBounds() { if (mUpdateMovementBoundsRunnable != null) { mUpdateMovementBoundsRunnable.run(); } } /** * Notifies the floating coordinator that we're moving, and sets the animating to bounds so * we return these bounds from Loading Loading @@ -720,7 +697,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** * Directly resizes the PiP to the given {@param bounds}. */ private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) { void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) { if (mPipBoundsState.getMotionBoundsState().isInMotion()) { // Do not carry out any resizing if we are dragging or physics animator is running. return; Loading Loading @@ -813,7 +790,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); // Signal that the transition is done - should update transition state by default. mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */); mPipScheduler.scheduleFinishResizePip(destinationBounds, false /* configAtEnd */); } private void startResizeAnimation(SurfaceControl.Transaction startTx, Loading @@ -829,8 +806,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), destinationBounds, duration, 0f /* angle */); animator.setAnimationEndCallback(() -> { mUpdateBoundsCallback.accept(destinationBounds); // In case an ongoing drag/fling was present before a deterministic resize transition // kicked in, we need to update the update bounds properly before cleaning in-motion // state. Loading @@ -839,7 +814,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); // Signal that we are done with resize transition mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */); mPipScheduler.scheduleFinishResizePip(destinationBounds, true /* configAtEnd */); }); animator.start(); } Loading @@ -849,7 +824,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, // The physics animation ended, though we may not necessarily be done animating, such as // when we're still dragging after moving out of the magnetic target. Only set the final // bounds state and clear motion bounds completely if the whole animation is over. mPipBoundsState.setBounds(mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded(); } mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java +4 −15 Original line number Diff line number Diff line Loading @@ -50,7 +50,6 @@ import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.pip2.animation.PipResizeAnimator; import java.io.PrintWriter; import java.util.function.Consumer; /** * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to Loading Loading @@ -86,8 +85,6 @@ public class PipResizeGestureHandler implements private final Rect mUserResizeBounds = new Rect(); private final Rect mDownBounds = new Rect(); private final Rect mStartBoundsAfterRelease = new Rect(); private final Runnable mUpdateMovementBoundsRunnable; private final Consumer<Rect> mUpdateResizeBoundsCallback; private float mTouchSlop; Loading Loading @@ -121,7 +118,6 @@ public class PipResizeGestureHandler implements PipTouchState pipTouchState, PipScheduler pipScheduler, PipTransitionState pipTransitionState, Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, ShellExecutor mainExecutor, Loading @@ -138,18 +134,9 @@ public class PipResizeGestureHandler implements mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; mPhonePipMenuController = menuActivityController; mPipUiEventLogger = pipUiEventLogger; mPinchResizingAlgorithm = new PipPinchResizingAlgorithm(); mUpdateResizeBoundsCallback = (rect) -> { mUserResizeBounds.set(rect); // mMotionHelper.synchronizePinnedStackBounds(); mPipBoundsState.setBounds(rect); mUpdateMovementBoundsRunnable.run(); resetState(); }; } void init() { Loading Loading @@ -563,11 +550,13 @@ public class PipResizeGestureHandler implements mLastResizeBounds, duration, mAngle); animator.setAnimationEndCallback(() -> { // All motion operations have actually finished, so make bounds cache updates. mUpdateResizeBoundsCallback.accept(mLastResizeBounds); mUserResizeBounds.set(mLastResizeBounds); resetState(); cleanUpHighPerfSessionMaybe(); // Signal that we are done with resize transition mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */); mPipScheduler.scheduleFinishResizePip( mLastResizeBounds, true /* configAtEnd */); }); animator.start(); break; Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +29 −1 Original line number Diff line number Diff line Loading @@ -52,11 +52,14 @@ public class PipScheduler { private final Context mContext; private final PipBoundsState mPipBoundsState; private final PhonePipMenuController mPipMenuController; private final ShellExecutor mMainExecutor; private final PipTransitionState mPipTransitionState; private PipSchedulerReceiver mSchedulerReceiver; private PipTransitionController mPipTransitionController; @Nullable private Runnable mUpdateMovementBoundsRunnable; /** * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. * This is used for a broadcast receiver to resolve intents. This should be removed once Loading Loading @@ -94,10 +97,12 @@ public class PipScheduler { public PipScheduler(Context context, PipBoundsState pipBoundsState, PhonePipMenuController pipMenuController, ShellExecutor mainExecutor, PipTransitionState pipTransitionState) { mContext = context; mPipBoundsState = pipBoundsState; mPipMenuController = pipMenuController; mMainExecutor = mainExecutor; mPipTransitionState = pipTransitionState; Loading Loading @@ -189,9 +194,13 @@ public class PipScheduler { * Signals to Core to finish the PiP resize transition. * Note that we do not allow any actual WM Core changes at this point. * * @param toBounds destination bounds used only for internal state updates - not sent to Core. * @param configAtEnd true if we are waiting for config updates at the end of the transition. */ public void scheduleFinishResizePip(boolean configAtEnd) { public void scheduleFinishResizePip(Rect toBounds, boolean configAtEnd) { // Make updates to the internal state to reflect new bounds onFinishingPipResize(toBounds); SurfaceControl.Transaction tx = null; if (configAtEnd) { tx = new SurfaceControl.Transaction(); Loading Loading @@ -238,4 +247,23 @@ public class PipScheduler { tx.setMatrix(leash, transformTensor, mMatrixTmp); tx.apply(); } void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) { mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; } private void maybeUpdateMovementBounds() { if (mUpdateMovementBoundsRunnable != null) { mUpdateMovementBoundsRunnable.run(); } } private void onFinishingPipResize(Rect newBounds) { if (mPipBoundsState.getBounds().equals(newBounds)) { return; } mPipBoundsState.setBounds(newBounds); mPipMenuController.updateMenuLayout(newBounds); maybeUpdateMovementBounds(); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java +20 −3 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import com.android.wm.shell.pip2.phone.PhonePipMenuController; import com.android.wm.shell.pip2.phone.PipController; import com.android.wm.shell.pip2.phone.PipMotionHelper; import com.android.wm.shell.pip2.phone.PipScheduler; import com.android.wm.shell.pip2.phone.PipTaskListener; import com.android.wm.shell.pip2.phone.PipTouchHandler; import com.android.wm.shell.pip2.phone.PipTransition; import com.android.wm.shell.pip2.phone.PipTransitionState; Loading Loading @@ -73,12 +74,13 @@ public abstract class Pip2Module { PipBoundsAlgorithm pipBoundsAlgorithm, Optional<PipController> pipController, PipTouchHandler pipTouchHandler, PipTaskListener pipTaskListener, @NonNull PipScheduler pipScheduler, @NonNull PipTransitionState pipStackListenerController, @NonNull PipUiStateChangeController pipUiStateChangeController) { return new PipTransition(context, shellInit, shellTaskOrganizer, transitions, pipBoundsState, null, pipBoundsAlgorithm, pipScheduler, pipStackListenerController, pipUiStateChangeController); pipBoundsState, null, pipBoundsAlgorithm, pipTaskListener, pipScheduler, pipStackListenerController, pipUiStateChangeController); } @WMSingleton Loading Loading @@ -123,9 +125,11 @@ public abstract class Pip2Module { @Provides static PipScheduler providePipScheduler(Context context, PipBoundsState pipBoundsState, PhonePipMenuController pipMenuController, @ShellMainThread ShellExecutor mainExecutor, PipTransitionState pipTransitionState) { return new PipScheduler(context, pipBoundsState, mainExecutor, pipTransitionState); return new PipScheduler(context, pipBoundsState, pipMenuController, mainExecutor, pipTransitionState); } @WMSingleton Loading Loading @@ -190,4 +194,17 @@ public abstract class Pip2Module { PipTransitionState pipTransitionState) { return new PipUiStateChangeController(pipTransitionState); } @WMSingleton @Provides static PipTaskListener providePipTaskListener(Context context, ShellTaskOrganizer shellTaskOrganizer, PipTransitionState pipTransitionState, PipScheduler pipScheduler, PipBoundsState pipBoundsState, PipBoundsAlgorithm pipBoundsAlgorithm, @ShellMainThread ShellExecutor mainExecutor) { return new PipTaskListener(context, shellTaskOrganizer, pipTransitionState, pipScheduler, pipBoundsState, pipBoundsAlgorithm, mainExecutor); } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java +3 −2 Original line number Diff line number Diff line Loading @@ -134,9 +134,10 @@ public class PipResizeAnimator extends ValueAnimator Rect baseBounds, Rect targetBounds, float degrees) { Matrix transformTensor = new Matrix(); final float[] mMatrixTmp = new float[9]; final float scale = (float) targetBounds.width() / baseBounds.width(); final float scaleX = (float) targetBounds.width() / baseBounds.width(); final float scaleY = (float) targetBounds.height() / baseBounds.height(); transformTensor.setScale(scale, scale); transformTensor.setScale(scaleX, scaleY); transformTensor.postTranslate(targetBounds.left, targetBounds.top); transformTensor.postRotate(degrees, targetBounds.centerX(), targetBounds.centerY()); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +3 −29 Original line number Diff line number Diff line Loading @@ -56,7 +56,6 @@ import kotlin.Unit; import kotlin.jvm.functions.Function0; import java.util.Optional; import java.util.function.Consumer; /** * A helper to animate and manipulate the PiP. Loading Loading @@ -134,18 +133,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig = new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_NO_BOUNCY); @Nullable private Runnable mUpdateMovementBoundsRunnable; private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> { if (mPipBoundsState.getBounds().equals(newBounds)) { return; } mMenuController.updateMenuLayout(newBounds); mPipBoundsState.setBounds(newBounds); maybeUpdateMovementBounds(); }; /** * Whether we're springing to the touch event location (vs. moving it to that position * instantly). We spring-to-touch after PIP is dragged out of the magnetic target, since it was Loading Loading @@ -683,16 +670,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); } void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) { mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; } private void maybeUpdateMovementBounds() { if (mUpdateMovementBoundsRunnable != null) { mUpdateMovementBoundsRunnable.run(); } } /** * Notifies the floating coordinator that we're moving, and sets the animating to bounds so * we return these bounds from Loading Loading @@ -720,7 +697,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** * Directly resizes the PiP to the given {@param bounds}. */ private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) { void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) { if (mPipBoundsState.getMotionBoundsState().isInMotion()) { // Do not carry out any resizing if we are dragging or physics animator is running. return; Loading Loading @@ -813,7 +790,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); // Signal that the transition is done - should update transition state by default. mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */); mPipScheduler.scheduleFinishResizePip(destinationBounds, false /* configAtEnd */); } private void startResizeAnimation(SurfaceControl.Transaction startTx, Loading @@ -829,8 +806,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(), destinationBounds, duration, 0f /* angle */); animator.setAnimationEndCallback(() -> { mUpdateBoundsCallback.accept(destinationBounds); // In case an ongoing drag/fling was present before a deterministic resize transition // kicked in, we need to update the update bounds properly before cleaning in-motion // state. Loading @@ -839,7 +814,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cleanUpHighPerfSessionMaybe(); // Signal that we are done with resize transition mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */); mPipScheduler.scheduleFinishResizePip(destinationBounds, true /* configAtEnd */); }); animator.start(); } Loading @@ -849,7 +824,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, // The physics animation ended, though we may not necessarily be done animating, such as // when we're still dragging after moving out of the magnetic target. Only set the final // bounds state and clear motion bounds completely if the whole animation is over. mPipBoundsState.setBounds(mPipBoundsState.getMotionBoundsState().getBoundsInMotion()); mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded(); } mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java +4 −15 Original line number Diff line number Diff line Loading @@ -50,7 +50,6 @@ import com.android.wm.shell.common.pip.PipUiEventLogger; import com.android.wm.shell.pip2.animation.PipResizeAnimator; import java.io.PrintWriter; import java.util.function.Consumer; /** * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to Loading Loading @@ -86,8 +85,6 @@ public class PipResizeGestureHandler implements private final Rect mUserResizeBounds = new Rect(); private final Rect mDownBounds = new Rect(); private final Rect mStartBoundsAfterRelease = new Rect(); private final Runnable mUpdateMovementBoundsRunnable; private final Consumer<Rect> mUpdateResizeBoundsCallback; private float mTouchSlop; Loading Loading @@ -121,7 +118,6 @@ public class PipResizeGestureHandler implements PipTouchState pipTouchState, PipScheduler pipScheduler, PipTransitionState pipTransitionState, Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController, ShellExecutor mainExecutor, Loading @@ -138,18 +134,9 @@ public class PipResizeGestureHandler implements mPipTransitionState = pipTransitionState; mPipTransitionState.addPipTransitionStateChangedListener(this); mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; mPhonePipMenuController = menuActivityController; mPipUiEventLogger = pipUiEventLogger; mPinchResizingAlgorithm = new PipPinchResizingAlgorithm(); mUpdateResizeBoundsCallback = (rect) -> { mUserResizeBounds.set(rect); // mMotionHelper.synchronizePinnedStackBounds(); mPipBoundsState.setBounds(rect); mUpdateMovementBoundsRunnable.run(); resetState(); }; } void init() { Loading Loading @@ -563,11 +550,13 @@ public class PipResizeGestureHandler implements mLastResizeBounds, duration, mAngle); animator.setAnimationEndCallback(() -> { // All motion operations have actually finished, so make bounds cache updates. mUpdateResizeBoundsCallback.accept(mLastResizeBounds); mUserResizeBounds.set(mLastResizeBounds); resetState(); cleanUpHighPerfSessionMaybe(); // Signal that we are done with resize transition mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */); mPipScheduler.scheduleFinishResizePip( mLastResizeBounds, true /* configAtEnd */); }); animator.start(); break; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +29 −1 Original line number Diff line number Diff line Loading @@ -52,11 +52,14 @@ public class PipScheduler { private final Context mContext; private final PipBoundsState mPipBoundsState; private final PhonePipMenuController mPipMenuController; private final ShellExecutor mMainExecutor; private final PipTransitionState mPipTransitionState; private PipSchedulerReceiver mSchedulerReceiver; private PipTransitionController mPipTransitionController; @Nullable private Runnable mUpdateMovementBoundsRunnable; /** * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell. * This is used for a broadcast receiver to resolve intents. This should be removed once Loading Loading @@ -94,10 +97,12 @@ public class PipScheduler { public PipScheduler(Context context, PipBoundsState pipBoundsState, PhonePipMenuController pipMenuController, ShellExecutor mainExecutor, PipTransitionState pipTransitionState) { mContext = context; mPipBoundsState = pipBoundsState; mPipMenuController = pipMenuController; mMainExecutor = mainExecutor; mPipTransitionState = pipTransitionState; Loading Loading @@ -189,9 +194,13 @@ public class PipScheduler { * Signals to Core to finish the PiP resize transition. * Note that we do not allow any actual WM Core changes at this point. * * @param toBounds destination bounds used only for internal state updates - not sent to Core. * @param configAtEnd true if we are waiting for config updates at the end of the transition. */ public void scheduleFinishResizePip(boolean configAtEnd) { public void scheduleFinishResizePip(Rect toBounds, boolean configAtEnd) { // Make updates to the internal state to reflect new bounds onFinishingPipResize(toBounds); SurfaceControl.Transaction tx = null; if (configAtEnd) { tx = new SurfaceControl.Transaction(); Loading Loading @@ -238,4 +247,23 @@ public class PipScheduler { tx.setMatrix(leash, transformTensor, mMatrixTmp); tx.apply(); } void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) { mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; } private void maybeUpdateMovementBounds() { if (mUpdateMovementBoundsRunnable != null) { mUpdateMovementBoundsRunnable.run(); } } private void onFinishingPipResize(Rect newBounds) { if (mPipBoundsState.getBounds().equals(newBounds)) { return; } mPipBoundsState.setBounds(newBounds); mPipMenuController.updateMenuLayout(newBounds); maybeUpdateMovementBounds(); } }