Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +26 −17 Original line number Diff line number Diff line Loading @@ -64,9 +64,9 @@ import com.android.internal.os.SomeArgs; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.pip.phone.PipUpdateThread; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -251,7 +251,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * If set to {@code true}, the entering animation will be skipped and we will wait for * {@link #onFixedRotationFinished(int)} callback to actually enter PiP. */ private boolean mShouldDeferEnteringPip; private boolean mWaitForFixedRotation; /** * If set to {@code true}, no entering PiP transition would be kicked off and most likely Loading @@ -259,7 +259,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * auto PiP-able Activity to home. * See also {@link #startSwipePipToHome(ComponentName, ActivityInfo, PictureInPictureParams)}. */ private boolean mShouldIgnoreEnteringPipTransition; private boolean mInSwipePipToHomeTransition; public PipTaskOrganizer(Context context, @NonNull PipBoundsState pipBoundsState, @NonNull PipBoundsAlgorithm boundsHandler, Loading Loading @@ -304,7 +304,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } public boolean isDeferringEnterPipAnimation() { return mState.isInPip() && mShouldDeferEnteringPip; return mState.isInPip() && mWaitForFixedRotation; } /** Loading Loading @@ -336,9 +336,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, PictureInPictureParams pictureInPictureParams) { mShouldIgnoreEnteringPipTransition = true; mInSwipePipToHomeTransition = true; sendOnPipTransitionStarted(componentName, TRANSITION_DIRECTION_TO_PIP); setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo); // disable the conflicting transaction from fixed rotation, see also // onFixedRotationStarted and onFixedRotationFinished mWaitForFixedRotation = false; return mPipBoundsAlgorithm.getEntryDestinationBounds(); } Loading @@ -348,7 +351,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { // do nothing if there is no startSwipePipToHome being called before if (mShouldIgnoreEnteringPipTransition) { if (mInSwipePipToHomeTransition) { mPipBoundsState.setBounds(destinationBounds); } } Loading Loading @@ -502,7 +505,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipMenuController.attach(leash); if (mShouldIgnoreEnteringPipTransition) { if (mInSwipePipToHomeTransition) { final Rect destinationBounds = mPipBoundsState.getBounds(); // animation is finished in the Launcher and here we directly apply the final touch. applyEnterPipSyncTransaction(destinationBounds, () -> { Loading @@ -510,11 +513,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, finishResizeForMenu(destinationBounds); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); }); mShouldIgnoreEnteringPipTransition = false; mInSwipePipToHomeTransition = false; return; } if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing"); // if deferred, hide the surface till fixed rotation is completed final SurfaceControl.Transaction tx = Loading Loading @@ -666,8 +669,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, Log.wtf(TAG, "Unrecognized token: " + token); return; } mShouldDeferEnteringPip = false; mShouldIgnoreEnteringPipTransition = false; mWaitForFixedRotation = false; mInSwipePipToHomeTransition = false; mPictureInPictureParams = null; mState = State.UNDEFINED; mPipUiEventLoggerLogger.setTaskInfo(null); Loading @@ -694,17 +697,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @Override public void onFixedRotationStarted(int displayId, int newRotation) { mShouldDeferEnteringPip = true; mWaitForFixedRotation = true; } @Override public void onFixedRotationFinished(int displayId) { if (mShouldDeferEnteringPip && mState.isInPip()) { if (mWaitForFixedRotation && mState.isInPip()) { final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); // schedule a regular animation to ensure all the callbacks are still being sent enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */); } mShouldDeferEnteringPip = false; mWaitForFixedRotation = false; } /** Loading @@ -723,6 +726,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, public void onMovementBoundsChanged(Rect destinationBoundsOut, boolean fromRotation, boolean fromImeAdjustment, boolean fromShelfAdjustment, WindowContainerTransaction wct) { // note that this can be called when swiping pip to home is happening. For instance, // swiping an app in landscape to portrait home. skip this entirely if that's the case. if (mInSwipePipToHomeTransition && fromRotation) { if (DEBUG) Log.d(TAG, "skip onMovementBoundsChanged due to swipe-pip-to-home"); return; } final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() Loading Loading @@ -806,7 +815,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void scheduleAnimateResizePip(Rect toBounds, int duration, Consumer<Rect> updateBoundsCallback) { if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred"); return; } Loading @@ -820,7 +829,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration, Consumer<Rect> updateBoundsCallback) { if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred"); return; } Loading Loading @@ -922,7 +931,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (mState.shouldBlockResizeRequest()) { return; } if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred"); return; } Loading packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java +34 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.systemui.shared.pip; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.view.Choreographer; import android.view.Surface; import android.view.SurfaceControl; /** Loading Loading @@ -50,8 +52,32 @@ public class PipSurfaceTransactionHelper { .setPosition(leash, left, top); } public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds) { public void scaleAndRotate(SurfaceControl.Transaction tx, SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, Rect insets, float degree, float positionX, float positionY) { mTmpSourceRectF.set(sourceBounds); mTmpDestinationRect.set(sourceBounds); mTmpDestinationRect.inset(insets); // Scale by the shortest edge and offset such that the top/left of the scaled inset // source rect aligns with the top/left of the destination bounds final float scale = sourceBounds.width() <= sourceBounds.height() ? (float) destinationBounds.width() / sourceBounds.width() : (float) destinationBounds.height() / sourceBounds.height(); mTmpTransform.setRotate(degree, 0, 0); mTmpTransform.postScale(scale, scale); tx.setMatrix(leash, mTmpTransform, mTmpFloat9) .setWindowCrop(leash, mTmpDestinationRect) .setPosition(leash, positionX, positionY); } public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds, @Surface.Rotation int rotation) { resetScale(tx, leash, destinationBounds); if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) { final int degree = (rotation == Surface.ROTATION_90) ? -90 : 90; mTmpTransform.setRotate(degree, 0, 0); tx.setMatrix(leash, mTmpTransform, mTmpFloat9); } resetCornerRadius(tx, leash); crop(tx, leash, destinationBounds); } Loading @@ -71,4 +97,11 @@ public class PipSurfaceTransactionHelper { tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height()) .setPosition(leash, destinationBounds.left, destinationBounds.top); } /** @return {@link SurfaceControl.Transaction} instance with vsync-id */ public static SurfaceControl.Transaction newSurfaceControlTransaction() { final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId()); return tx; } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +26 −17 Original line number Diff line number Diff line Loading @@ -64,9 +64,9 @@ import com.android.internal.os.SomeArgs; import com.android.wm.shell.R; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import com.android.wm.shell.pip.phone.PipMotionHelper; import com.android.wm.shell.pip.phone.PipUpdateThread; import com.android.wm.shell.legacysplitscreen.LegacySplitScreen; import java.io.PrintWriter; import java.util.ArrayList; Loading Loading @@ -251,7 +251,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * If set to {@code true}, the entering animation will be skipped and we will wait for * {@link #onFixedRotationFinished(int)} callback to actually enter PiP. */ private boolean mShouldDeferEnteringPip; private boolean mWaitForFixedRotation; /** * If set to {@code true}, no entering PiP transition would be kicked off and most likely Loading @@ -259,7 +259,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, * auto PiP-able Activity to home. * See also {@link #startSwipePipToHome(ComponentName, ActivityInfo, PictureInPictureParams)}. */ private boolean mShouldIgnoreEnteringPipTransition; private boolean mInSwipePipToHomeTransition; public PipTaskOrganizer(Context context, @NonNull PipBoundsState pipBoundsState, @NonNull PipBoundsAlgorithm boundsHandler, Loading Loading @@ -304,7 +304,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } public boolean isDeferringEnterPipAnimation() { return mState.isInPip() && mShouldDeferEnteringPip; return mState.isInPip() && mWaitForFixedRotation; } /** Loading Loading @@ -336,9 +336,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, PictureInPictureParams pictureInPictureParams) { mShouldIgnoreEnteringPipTransition = true; mInSwipePipToHomeTransition = true; sendOnPipTransitionStarted(componentName, TRANSITION_DIRECTION_TO_PIP); setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo); // disable the conflicting transaction from fixed rotation, see also // onFixedRotationStarted and onFixedRotationFinished mWaitForFixedRotation = false; return mPipBoundsAlgorithm.getEntryDestinationBounds(); } Loading @@ -348,7 +351,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { // do nothing if there is no startSwipePipToHome being called before if (mShouldIgnoreEnteringPipTransition) { if (mInSwipePipToHomeTransition) { mPipBoundsState.setBounds(destinationBounds); } } Loading Loading @@ -502,7 +505,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipMenuController.attach(leash); if (mShouldIgnoreEnteringPipTransition) { if (mInSwipePipToHomeTransition) { final Rect destinationBounds = mPipBoundsState.getBounds(); // animation is finished in the Launcher and here we directly apply the final touch. applyEnterPipSyncTransaction(destinationBounds, () -> { Loading @@ -510,11 +513,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, finishResizeForMenu(destinationBounds); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); }); mShouldIgnoreEnteringPipTransition = false; mInSwipePipToHomeTransition = false; return; } if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing"); // if deferred, hide the surface till fixed rotation is completed final SurfaceControl.Transaction tx = Loading Loading @@ -666,8 +669,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, Log.wtf(TAG, "Unrecognized token: " + token); return; } mShouldDeferEnteringPip = false; mShouldIgnoreEnteringPipTransition = false; mWaitForFixedRotation = false; mInSwipePipToHomeTransition = false; mPictureInPictureParams = null; mState = State.UNDEFINED; mPipUiEventLoggerLogger.setTaskInfo(null); Loading @@ -694,17 +697,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @Override public void onFixedRotationStarted(int displayId, int newRotation) { mShouldDeferEnteringPip = true; mWaitForFixedRotation = true; } @Override public void onFixedRotationFinished(int displayId) { if (mShouldDeferEnteringPip && mState.isInPip()) { if (mWaitForFixedRotation && mState.isInPip()) { final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); // schedule a regular animation to ensure all the callbacks are still being sent enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */); } mShouldDeferEnteringPip = false; mWaitForFixedRotation = false; } /** Loading @@ -723,6 +726,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, public void onMovementBoundsChanged(Rect destinationBoundsOut, boolean fromRotation, boolean fromImeAdjustment, boolean fromShelfAdjustment, WindowContainerTransaction wct) { // note that this can be called when swiping pip to home is happening. For instance, // swiping an app in landscape to portrait home. skip this entirely if that's the case. if (mInSwipePipToHomeTransition && fromRotation) { if (DEBUG) Log.d(TAG, "skip onMovementBoundsChanged due to swipe-pip-to-home"); return; } final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() Loading Loading @@ -806,7 +815,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void scheduleAnimateResizePip(Rect toBounds, int duration, Consumer<Rect> updateBoundsCallback) { if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred"); return; } Loading @@ -820,7 +829,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void scheduleAnimateResizePip(Rect fromBounds, Rect toBounds, int duration, Consumer<Rect> updateBoundsCallback) { if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred"); return; } Loading Loading @@ -922,7 +931,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (mState.shouldBlockResizeRequest()) { return; } if (mShouldDeferEnteringPip) { if (mWaitForFixedRotation) { Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred"); return; } Loading
packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java +34 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.systemui.shared.pip; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; import android.view.Choreographer; import android.view.Surface; import android.view.SurfaceControl; /** Loading Loading @@ -50,8 +52,32 @@ public class PipSurfaceTransactionHelper { .setPosition(leash, left, top); } public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds) { public void scaleAndRotate(SurfaceControl.Transaction tx, SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, Rect insets, float degree, float positionX, float positionY) { mTmpSourceRectF.set(sourceBounds); mTmpDestinationRect.set(sourceBounds); mTmpDestinationRect.inset(insets); // Scale by the shortest edge and offset such that the top/left of the scaled inset // source rect aligns with the top/left of the destination bounds final float scale = sourceBounds.width() <= sourceBounds.height() ? (float) destinationBounds.width() / sourceBounds.width() : (float) destinationBounds.height() / sourceBounds.height(); mTmpTransform.setRotate(degree, 0, 0); mTmpTransform.postScale(scale, scale); tx.setMatrix(leash, mTmpTransform, mTmpFloat9) .setWindowCrop(leash, mTmpDestinationRect) .setPosition(leash, positionX, positionY); } public void reset(SurfaceControl.Transaction tx, SurfaceControl leash, Rect destinationBounds, @Surface.Rotation int rotation) { resetScale(tx, leash, destinationBounds); if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) { final int degree = (rotation == Surface.ROTATION_90) ? -90 : 90; mTmpTransform.setRotate(degree, 0, 0); tx.setMatrix(leash, mTmpTransform, mTmpFloat9); } resetCornerRadius(tx, leash); crop(tx, leash, destinationBounds); } Loading @@ -71,4 +97,11 @@ public class PipSurfaceTransactionHelper { tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height()) .setPosition(leash, destinationBounds.left, destinationBounds.top); } /** @return {@link SurfaceControl.Transaction} instance with vsync-id */ public static SurfaceControl.Transaction newSurfaceControlTransaction() { final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); tx.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId()); return tx; } }