Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java 0 → 100644 +159 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.pip2.animation; import android.animation.Animator; import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; import android.view.Surface; import android.view.SurfaceControl; import android.window.TransitionInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.wm.shell.R; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import com.android.wm.shell.shared.animation.Interpolators; /** * Animator that handles bounds animations for entering PIP. */ public class PipEnterAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { @NonNull private final SurfaceControl mLeash; private final SurfaceControl.Transaction mStartTransaction; private final SurfaceControl.Transaction mFinishTransaction; // Bounds updated by the evaluator as animator is running. private final Rect mAnimatedRect = new Rect(); private final RectEvaluator mRectEvaluator; private final Rect mEndBounds = new Rect(); @Nullable private final Rect mSourceRectHint; private final @Surface.Rotation int mRotation; @Nullable private Runnable mAnimationStartCallback; @Nullable private Runnable mAnimationEndCallback; private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; // Internal state representing initial transform - cached to avoid recalculation. private final PointF mInitScale = new PointF(); private final PointF mInitPos = new PointF(); private final Rect mInitCrop = new Rect(); public PipEnterAnimator(Context context, @NonNull SurfaceControl leash, SurfaceControl.Transaction startTransaction, SurfaceControl.Transaction finishTransaction, @NonNull Rect endBounds, @Nullable Rect sourceRectHint, @Surface.Rotation int rotation) { mLeash = leash; mStartTransaction = startTransaction; mFinishTransaction = finishTransaction; mRectEvaluator = new RectEvaluator(mAnimatedRect); mEndBounds.set(endBounds); mSourceRectHint = sourceRectHint != null ? new Rect(sourceRectHint) : null; mRotation = rotation; mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); final int enterAnimationDuration = context.getResources() .getInteger(R.integer.config_pipEnterAnimationDuration); setDuration(enterAnimationDuration); setFloatValues(0f, 1f); setInterpolator(Interpolators.FAST_OUT_SLOW_IN); addListener(this); addUpdateListener(this); } public void setAnimationStartCallback(@NonNull Runnable runnable) { mAnimationStartCallback = runnable; } public void setAnimationEndCallback(@NonNull Runnable runnable) { mAnimationEndCallback = runnable; } @Override public void onAnimationStart(@NonNull Animator animation) { if (mAnimationStartCallback != null) { mAnimationStartCallback.run(); } if (mStartTransaction != null) { onEnterAnimationUpdate(mInitScale, mInitPos, mInitCrop, 0f /* fraction */, mStartTransaction); mStartTransaction.apply(); } } @Override public void onAnimationEnd(@NonNull Animator animation) { if (mAnimationEndCallback != null) { mAnimationEndCallback.run(); } } @Override public void onAnimationUpdate(@NonNull ValueAnimator animation) { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final float fraction = getAnimatedFraction(); onEnterAnimationUpdate(mInitScale, mInitPos, mInitCrop, fraction, tx); tx.apply(); } private void onEnterAnimationUpdate(PointF initScale, PointF initPos, Rect initCrop, float fraction, SurfaceControl.Transaction tx) { float scaleX = 1 + (initScale.x - 1) * (1 - fraction); float scaleY = 1 + (initScale.y - 1) * (1 - fraction); tx.setScale(mLeash, scaleX, scaleY); float posX = initPos.x + (mEndBounds.left - initPos.x) * fraction; float posY = initPos.y + (mEndBounds.top - initPos.y) * fraction; tx.setPosition(mLeash, posX, posY); Rect endCrop = new Rect(mEndBounds); endCrop.offsetTo(0, 0); mRectEvaluator.evaluate(fraction, initCrop, endCrop); tx.setCrop(mLeash, mAnimatedRect); } // no-ops @Override public void onAnimationCancel(@NonNull Animator animation) {} @Override public void onAnimationRepeat(@NonNull Animator animation) {} /** * Caches the initial transform relevant values for the bounds enter animation. * * Since enter PiP makes use of a config-at-end transition, initial transform needs to be * calculated differently from generic transitions. * @param pipChange PiP change received as a transition target. */ public void setEnterStartState(@NonNull TransitionInfo.Change pipChange) { PipUtils.calcStartTransform(pipChange, mInitScale, mInitPos, mInitCrop); } } libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterExitAnimator.java→libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java +22 −45 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.wm.shell.pip2.animation; import android.animation.Animator; import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.content.Context; import android.graphics.Rect; import android.view.Surface; Loading @@ -30,35 +29,22 @@ import androidx.annotation.Nullable; import com.android.wm.shell.R; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import com.android.wm.shell.shared.animation.Interpolators; /** * Animator that handles bounds animations for entering / exiting PIP. * Animator that handles bounds animations for exit-via-expanding PIP. */ public class PipEnterExitAnimator extends ValueAnimator public class PipExpandAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { @IntDef(prefix = {"BOUNDS_"}, value = { BOUNDS_ENTER, BOUNDS_EXIT }) @Retention(RetentionPolicy.SOURCE) public @interface BOUNDS {} public static final int BOUNDS_ENTER = 0; public static final int BOUNDS_EXIT = 1; @NonNull private final SurfaceControl mLeash; @NonNull private final SurfaceControl mLeash; private final SurfaceControl.Transaction mStartTransaction; private final SurfaceControl.Transaction mFinishTransaction; private final int mEnterExitAnimationDuration; private final @BOUNDS int mDirection; private final @Surface.Rotation int mRotation; // optional callbacks for tracking animation start and end @Nullable private Runnable mAnimationStartCallback; @Nullable private Runnable mAnimationStartCallback; @Nullable private Runnable mAnimationEndCallback; private final Rect mBaseBounds = new Rect(); Loading @@ -78,7 +64,7 @@ public class PipEnterExitAnimator extends ValueAnimator private final RectEvaluator mInsetEvaluator; private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; public PipEnterExitAnimator(Context context, public PipExpandAnimator(Context context, @NonNull SurfaceControl leash, SurfaceControl.Transaction startTransaction, SurfaceControl.Transaction finishTransaction, Loading @@ -86,7 +72,6 @@ public class PipEnterExitAnimator extends ValueAnimator @NonNull Rect startBounds, @NonNull Rect endBounds, @Nullable Rect sourceRectHint, @BOUNDS int direction, @Surface.Rotation int rotation) { mLeash = leash; mStartTransaction = startTransaction; Loading @@ -98,7 +83,6 @@ public class PipEnterExitAnimator extends ValueAnimator mRectEvaluator = new RectEvaluator(mAnimatedRect); mInsetEvaluator = new RectEvaluator(new Rect()); mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context); mDirection = direction; mRotation = rotation; mSourceRectHint = sourceRectHint != null ? new Rect(sourceRectHint) : null; Loading @@ -113,12 +97,14 @@ public class PipEnterExitAnimator extends ValueAnimator mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mEnterExitAnimationDuration = context.getResources() final int enterAnimationDuration = context.getResources() .getInteger(R.integer.config_pipEnterAnimationDuration); setDuration(enterAnimationDuration); setObjectValues(startBounds, endBounds); setDuration(mEnterExitAnimationDuration); setEvaluator(mRectEvaluator); setInterpolator(Interpolators.FAST_OUT_SLOW_IN); addListener(this); addUpdateListener(this); } Loading Loading @@ -147,9 +133,10 @@ public class PipEnterExitAnimator extends ValueAnimator // finishTransaction might override some state (eg. corner radii) so we want to // manually set the state to the end of the animation mPipSurfaceTransactionHelper.scaleAndCrop(mFinishTransaction, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, getInsets(1f), isInPipDirection(), 1f) .round(mFinishTransaction, mLeash, isInPipDirection()) .shadow(mFinishTransaction, mLeash, isInPipDirection()); mBaseBounds, mAnimatedRect, getInsets(1f), false /* isInPipDirection */, 1f) .round(mFinishTransaction, mLeash, false /* applyCornerRadius */) .shadow(mFinishTransaction, mLeash, false /* applyCornerRadius */); } if (mAnimationEndCallback != null) { mAnimationEndCallback.run(); Loading @@ -160,32 +147,22 @@ public class PipEnterExitAnimator extends ValueAnimator public void onAnimationUpdate(@NonNull ValueAnimator animation) { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final float fraction = getAnimatedFraction(); Rect insets = getInsets(fraction); // TODO (b/350801661): implement fixed rotation Rect insets = getInsets(fraction); mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, insets, isInPipDirection(), fraction) .round(tx, mLeash, isInPipDirection()) .shadow(tx, mLeash, isInPipDirection()); mBaseBounds, mAnimatedRect, insets, false /* isInPipDirection */, fraction) .round(tx, mLeash, false /* applyCornerRadius */) .shadow(tx, mLeash, false /* applyCornerRadius */); tx.apply(); } private Rect getInsets(float fraction) { Rect startInsets = isInPipDirection() ? mZeroInsets : mSourceRectHintInsets; Rect endInsets = isInPipDirection() ? mSourceRectHintInsets : mZeroInsets; final Rect startInsets = mSourceRectHintInsets; final Rect endInsets = mZeroInsets; return mInsetEvaluator.evaluate(fraction, startInsets, endInsets); } private boolean isInPipDirection() { return mDirection == BOUNDS_ENTER; } private boolean isOutPipDirection() { return mDirection == BOUNDS_EXIT; } // no-ops @Override Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +16 −31 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ import com.android.wm.shell.common.pip.PipMenuController; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip2.animation.PipAlphaAnimator; import com.android.wm.shell.pip2.animation.PipEnterExitAnimator; import com.android.wm.shell.pip2.animation.PipEnterAnimator; import com.android.wm.shell.pip2.animation.PipExpandAnimator; import com.android.wm.shell.shared.TransitionUtil; import com.android.wm.shell.shared.pip.PipContentOverlay; import com.android.wm.shell.sysui.ShellInit; Loading Loading @@ -218,6 +219,7 @@ public class PipTransition extends PipTransitionController implements @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { mFinishCallback = finishCallback; if (transition == mEnterTransition || info.getType() == TRANSIT_PIP) { mEnterTransition = null; // If we are in swipe PiP to Home transition we are ENTERING_PIP as a jumpcut transition Loading Loading @@ -258,6 +260,7 @@ public class PipTransition extends PipTransitionController implements if (isRemovePipTransition(info)) { return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); } mFinishCallback = null; return false; } Loading Loading @@ -297,7 +300,6 @@ public class PipTransition extends PipTransitionController implements mBoundsChangeDuration = BOUNDS_CHANGE_JUMPCUT_DURATION; } mFinishCallback = finishCallback; mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); return true; } Loading Loading @@ -349,7 +351,6 @@ public class PipTransition extends PipTransitionController implements startTransaction.setMatrix(pipLeash, transformTensor, matrixTmp); } startTransaction.apply(); finishCallback.onTransitionFinished(null /* finishWct */); finishInner(); return true; } Loading Loading @@ -386,14 +387,6 @@ public class PipTransition extends PipTransitionController implements return false; } WindowContainerToken pipTaskToken = pipChange.getContainer(); if (pipTaskToken == null) { return false; } WindowContainerTransaction finishWct = new WindowContainerTransaction(); SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); Rect startBounds = pipChange.getStartAbsBounds(); Rect endBounds = pipChange.getEndAbsBounds(); SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash; Loading @@ -405,29 +398,22 @@ public class PipTransition extends PipTransitionController implements sourceRectHint = pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint(); } // For opening type transitions, if there is a non-pip change of mode TO_FRONT/OPEN, // For opening type transitions, if there is a change of mode TO_FRONT/OPEN, // make sure that change has alpha of 1f, since it's init state might be set to alpha=0f // by the Transitions framework to simplify Task opening transitions. if (TransitionUtil.isOpeningType(info.getType())) { for (TransitionInfo.Change change : info.getChanges()) { if (change.getLeash() == null || change == pipChange) continue; if (change.getLeash() == null) continue; if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { startTransaction.setAlpha(change.getLeash(), 1f); } } } PipEnterExitAnimator animator = new PipEnterExitAnimator(mContext, pipLeash, startTransaction, finishTransaction, startBounds, startBounds, endBounds, sourceRectHint, PipEnterExitAnimator.BOUNDS_ENTER, Surface.ROTATION_0); tx.addTransactionCommittedListener(mPipScheduler.getMainExecutor(), this::finishInner); finishWct.setBoundsChangeTransaction(pipTaskToken, tx); animator.setAnimationEndCallback(() -> finishCallback.onTransitionFinished(finishWct)); PipEnterAnimator animator = new PipEnterAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, sourceRectHint, Surface.ROTATION_0); animator.setAnimationStartCallback(() -> animator.setEnterStartState(pipChange)); animator.setAnimationEndCallback(this::finishInner); animator.start(); return true; } Loading @@ -452,11 +438,8 @@ public class PipTransition extends PipTransitionController implements PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipLeash, startTransaction, PipAlphaAnimator.FADE_IN); animator.setAnimationEndCallback(() -> { finishCallback.onTransitionFinished(null); // This should update the pip transition state accordingly after we stop playing. finishInner(); }); animator.setAnimationEndCallback(this::finishInner); animator.start(); return true; Loading Loading @@ -510,9 +493,9 @@ public class PipTransition extends PipTransitionController implements sourceRectHint = mPipTaskListener.getPictureInPictureParams().getSourceRectHint(); } PipEnterExitAnimator animator = new PipEnterExitAnimator(mContext, pipLeash, PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, PipEnterExitAnimator.BOUNDS_EXIT, Surface.ROTATION_0); sourceRectHint, Surface.ROTATION_0); animator.setAnimationEndCallback(() -> { mPipTransitionState.setState(PipTransitionState.EXITED_PIP); Loading Loading @@ -631,6 +614,7 @@ public class PipTransition extends PipTransitionController implements // private void finishInner() { finishTransition(null /* tx */); if (mPipTransitionState.getSwipePipToHomeOverlay() != null) { startOverlayFadeoutAnimation(); } else if (mPipTransitionState.getState() == PipTransitionState.ENTERING_PIP) { Loading @@ -652,6 +636,7 @@ public class PipTransition extends PipTransitionController implements } if (mFinishCallback != null) { mFinishCallback.onTransitionFinished(wct); mFinishCallback = null; } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterAnimator.java 0 → 100644 +159 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.pip2.animation; import android.animation.Animator; import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; import android.view.Surface; import android.view.SurfaceControl; import android.window.TransitionInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.wm.shell.R; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import com.android.wm.shell.shared.animation.Interpolators; /** * Animator that handles bounds animations for entering PIP. */ public class PipEnterAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { @NonNull private final SurfaceControl mLeash; private final SurfaceControl.Transaction mStartTransaction; private final SurfaceControl.Transaction mFinishTransaction; // Bounds updated by the evaluator as animator is running. private final Rect mAnimatedRect = new Rect(); private final RectEvaluator mRectEvaluator; private final Rect mEndBounds = new Rect(); @Nullable private final Rect mSourceRectHint; private final @Surface.Rotation int mRotation; @Nullable private Runnable mAnimationStartCallback; @Nullable private Runnable mAnimationEndCallback; private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; // Internal state representing initial transform - cached to avoid recalculation. private final PointF mInitScale = new PointF(); private final PointF mInitPos = new PointF(); private final Rect mInitCrop = new Rect(); public PipEnterAnimator(Context context, @NonNull SurfaceControl leash, SurfaceControl.Transaction startTransaction, SurfaceControl.Transaction finishTransaction, @NonNull Rect endBounds, @Nullable Rect sourceRectHint, @Surface.Rotation int rotation) { mLeash = leash; mStartTransaction = startTransaction; mFinishTransaction = finishTransaction; mRectEvaluator = new RectEvaluator(mAnimatedRect); mEndBounds.set(endBounds); mSourceRectHint = sourceRectHint != null ? new Rect(sourceRectHint) : null; mRotation = rotation; mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); final int enterAnimationDuration = context.getResources() .getInteger(R.integer.config_pipEnterAnimationDuration); setDuration(enterAnimationDuration); setFloatValues(0f, 1f); setInterpolator(Interpolators.FAST_OUT_SLOW_IN); addListener(this); addUpdateListener(this); } public void setAnimationStartCallback(@NonNull Runnable runnable) { mAnimationStartCallback = runnable; } public void setAnimationEndCallback(@NonNull Runnable runnable) { mAnimationEndCallback = runnable; } @Override public void onAnimationStart(@NonNull Animator animation) { if (mAnimationStartCallback != null) { mAnimationStartCallback.run(); } if (mStartTransaction != null) { onEnterAnimationUpdate(mInitScale, mInitPos, mInitCrop, 0f /* fraction */, mStartTransaction); mStartTransaction.apply(); } } @Override public void onAnimationEnd(@NonNull Animator animation) { if (mAnimationEndCallback != null) { mAnimationEndCallback.run(); } } @Override public void onAnimationUpdate(@NonNull ValueAnimator animation) { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final float fraction = getAnimatedFraction(); onEnterAnimationUpdate(mInitScale, mInitPos, mInitCrop, fraction, tx); tx.apply(); } private void onEnterAnimationUpdate(PointF initScale, PointF initPos, Rect initCrop, float fraction, SurfaceControl.Transaction tx) { float scaleX = 1 + (initScale.x - 1) * (1 - fraction); float scaleY = 1 + (initScale.y - 1) * (1 - fraction); tx.setScale(mLeash, scaleX, scaleY); float posX = initPos.x + (mEndBounds.left - initPos.x) * fraction; float posY = initPos.y + (mEndBounds.top - initPos.y) * fraction; tx.setPosition(mLeash, posX, posY); Rect endCrop = new Rect(mEndBounds); endCrop.offsetTo(0, 0); mRectEvaluator.evaluate(fraction, initCrop, endCrop); tx.setCrop(mLeash, mAnimatedRect); } // no-ops @Override public void onAnimationCancel(@NonNull Animator animation) {} @Override public void onAnimationRepeat(@NonNull Animator animation) {} /** * Caches the initial transform relevant values for the bounds enter animation. * * Since enter PiP makes use of a config-at-end transition, initial transform needs to be * calculated differently from generic transitions. * @param pipChange PiP change received as a transition target. */ public void setEnterStartState(@NonNull TransitionInfo.Change pipChange) { PipUtils.calcStartTransform(pipChange, mInitScale, mInitPos, mInitCrop); } }
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipEnterExitAnimator.java→libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java +22 −45 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.wm.shell.pip2.animation; import android.animation.Animator; import android.animation.RectEvaluator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.content.Context; import android.graphics.Rect; import android.view.Surface; Loading @@ -30,35 +29,22 @@ import androidx.annotation.Nullable; import com.android.wm.shell.R; import com.android.wm.shell.pip2.PipSurfaceTransactionHelper; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import com.android.wm.shell.shared.animation.Interpolators; /** * Animator that handles bounds animations for entering / exiting PIP. * Animator that handles bounds animations for exit-via-expanding PIP. */ public class PipEnterExitAnimator extends ValueAnimator public class PipExpandAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { @IntDef(prefix = {"BOUNDS_"}, value = { BOUNDS_ENTER, BOUNDS_EXIT }) @Retention(RetentionPolicy.SOURCE) public @interface BOUNDS {} public static final int BOUNDS_ENTER = 0; public static final int BOUNDS_EXIT = 1; @NonNull private final SurfaceControl mLeash; @NonNull private final SurfaceControl mLeash; private final SurfaceControl.Transaction mStartTransaction; private final SurfaceControl.Transaction mFinishTransaction; private final int mEnterExitAnimationDuration; private final @BOUNDS int mDirection; private final @Surface.Rotation int mRotation; // optional callbacks for tracking animation start and end @Nullable private Runnable mAnimationStartCallback; @Nullable private Runnable mAnimationStartCallback; @Nullable private Runnable mAnimationEndCallback; private final Rect mBaseBounds = new Rect(); Loading @@ -78,7 +64,7 @@ public class PipEnterExitAnimator extends ValueAnimator private final RectEvaluator mInsetEvaluator; private final PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; public PipEnterExitAnimator(Context context, public PipExpandAnimator(Context context, @NonNull SurfaceControl leash, SurfaceControl.Transaction startTransaction, SurfaceControl.Transaction finishTransaction, Loading @@ -86,7 +72,6 @@ public class PipEnterExitAnimator extends ValueAnimator @NonNull Rect startBounds, @NonNull Rect endBounds, @Nullable Rect sourceRectHint, @BOUNDS int direction, @Surface.Rotation int rotation) { mLeash = leash; mStartTransaction = startTransaction; Loading @@ -98,7 +83,6 @@ public class PipEnterExitAnimator extends ValueAnimator mRectEvaluator = new RectEvaluator(mAnimatedRect); mInsetEvaluator = new RectEvaluator(new Rect()); mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context); mDirection = direction; mRotation = rotation; mSourceRectHint = sourceRectHint != null ? new Rect(sourceRectHint) : null; Loading @@ -113,12 +97,14 @@ public class PipEnterExitAnimator extends ValueAnimator mSurfaceControlTransactionFactory = new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory(); mEnterExitAnimationDuration = context.getResources() final int enterAnimationDuration = context.getResources() .getInteger(R.integer.config_pipEnterAnimationDuration); setDuration(enterAnimationDuration); setObjectValues(startBounds, endBounds); setDuration(mEnterExitAnimationDuration); setEvaluator(mRectEvaluator); setInterpolator(Interpolators.FAST_OUT_SLOW_IN); addListener(this); addUpdateListener(this); } Loading Loading @@ -147,9 +133,10 @@ public class PipEnterExitAnimator extends ValueAnimator // finishTransaction might override some state (eg. corner radii) so we want to // manually set the state to the end of the animation mPipSurfaceTransactionHelper.scaleAndCrop(mFinishTransaction, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, getInsets(1f), isInPipDirection(), 1f) .round(mFinishTransaction, mLeash, isInPipDirection()) .shadow(mFinishTransaction, mLeash, isInPipDirection()); mBaseBounds, mAnimatedRect, getInsets(1f), false /* isInPipDirection */, 1f) .round(mFinishTransaction, mLeash, false /* applyCornerRadius */) .shadow(mFinishTransaction, mLeash, false /* applyCornerRadius */); } if (mAnimationEndCallback != null) { mAnimationEndCallback.run(); Loading @@ -160,32 +147,22 @@ public class PipEnterExitAnimator extends ValueAnimator public void onAnimationUpdate(@NonNull ValueAnimator animation) { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final float fraction = getAnimatedFraction(); Rect insets = getInsets(fraction); // TODO (b/350801661): implement fixed rotation Rect insets = getInsets(fraction); mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, insets, isInPipDirection(), fraction) .round(tx, mLeash, isInPipDirection()) .shadow(tx, mLeash, isInPipDirection()); mBaseBounds, mAnimatedRect, insets, false /* isInPipDirection */, fraction) .round(tx, mLeash, false /* applyCornerRadius */) .shadow(tx, mLeash, false /* applyCornerRadius */); tx.apply(); } private Rect getInsets(float fraction) { Rect startInsets = isInPipDirection() ? mZeroInsets : mSourceRectHintInsets; Rect endInsets = isInPipDirection() ? mSourceRectHintInsets : mZeroInsets; final Rect startInsets = mSourceRectHintInsets; final Rect endInsets = mZeroInsets; return mInsetEvaluator.evaluate(fraction, startInsets, endInsets); } private boolean isInPipDirection() { return mDirection == BOUNDS_ENTER; } private boolean isOutPipDirection() { return mDirection == BOUNDS_EXIT; } // no-ops @Override Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +16 −31 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ import com.android.wm.shell.common.pip.PipMenuController; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip.PipTransitionController; import com.android.wm.shell.pip2.animation.PipAlphaAnimator; import com.android.wm.shell.pip2.animation.PipEnterExitAnimator; import com.android.wm.shell.pip2.animation.PipEnterAnimator; import com.android.wm.shell.pip2.animation.PipExpandAnimator; import com.android.wm.shell.shared.TransitionUtil; import com.android.wm.shell.shared.pip.PipContentOverlay; import com.android.wm.shell.sysui.ShellInit; Loading Loading @@ -218,6 +219,7 @@ public class PipTransition extends PipTransitionController implements @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { mFinishCallback = finishCallback; if (transition == mEnterTransition || info.getType() == TRANSIT_PIP) { mEnterTransition = null; // If we are in swipe PiP to Home transition we are ENTERING_PIP as a jumpcut transition Loading Loading @@ -258,6 +260,7 @@ public class PipTransition extends PipTransitionController implements if (isRemovePipTransition(info)) { return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); } mFinishCallback = null; return false; } Loading Loading @@ -297,7 +300,6 @@ public class PipTransition extends PipTransitionController implements mBoundsChangeDuration = BOUNDS_CHANGE_JUMPCUT_DURATION; } mFinishCallback = finishCallback; mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra); return true; } Loading Loading @@ -349,7 +351,6 @@ public class PipTransition extends PipTransitionController implements startTransaction.setMatrix(pipLeash, transformTensor, matrixTmp); } startTransaction.apply(); finishCallback.onTransitionFinished(null /* finishWct */); finishInner(); return true; } Loading Loading @@ -386,14 +387,6 @@ public class PipTransition extends PipTransitionController implements return false; } WindowContainerToken pipTaskToken = pipChange.getContainer(); if (pipTaskToken == null) { return false; } WindowContainerTransaction finishWct = new WindowContainerTransaction(); SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); Rect startBounds = pipChange.getStartAbsBounds(); Rect endBounds = pipChange.getEndAbsBounds(); SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash; Loading @@ -405,29 +398,22 @@ public class PipTransition extends PipTransitionController implements sourceRectHint = pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint(); } // For opening type transitions, if there is a non-pip change of mode TO_FRONT/OPEN, // For opening type transitions, if there is a change of mode TO_FRONT/OPEN, // make sure that change has alpha of 1f, since it's init state might be set to alpha=0f // by the Transitions framework to simplify Task opening transitions. if (TransitionUtil.isOpeningType(info.getType())) { for (TransitionInfo.Change change : info.getChanges()) { if (change.getLeash() == null || change == pipChange) continue; if (change.getLeash() == null) continue; if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) { startTransaction.setAlpha(change.getLeash(), 1f); } } } PipEnterExitAnimator animator = new PipEnterExitAnimator(mContext, pipLeash, startTransaction, finishTransaction, startBounds, startBounds, endBounds, sourceRectHint, PipEnterExitAnimator.BOUNDS_ENTER, Surface.ROTATION_0); tx.addTransactionCommittedListener(mPipScheduler.getMainExecutor(), this::finishInner); finishWct.setBoundsChangeTransaction(pipTaskToken, tx); animator.setAnimationEndCallback(() -> finishCallback.onTransitionFinished(finishWct)); PipEnterAnimator animator = new PipEnterAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, sourceRectHint, Surface.ROTATION_0); animator.setAnimationStartCallback(() -> animator.setEnterStartState(pipChange)); animator.setAnimationEndCallback(this::finishInner); animator.start(); return true; } Loading @@ -452,11 +438,8 @@ public class PipTransition extends PipTransitionController implements PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipLeash, startTransaction, PipAlphaAnimator.FADE_IN); animator.setAnimationEndCallback(() -> { finishCallback.onTransitionFinished(null); // This should update the pip transition state accordingly after we stop playing. finishInner(); }); animator.setAnimationEndCallback(this::finishInner); animator.start(); return true; Loading Loading @@ -510,9 +493,9 @@ public class PipTransition extends PipTransitionController implements sourceRectHint = mPipTaskListener.getPictureInPictureParams().getSourceRectHint(); } PipEnterExitAnimator animator = new PipEnterExitAnimator(mContext, pipLeash, PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, PipEnterExitAnimator.BOUNDS_EXIT, Surface.ROTATION_0); sourceRectHint, Surface.ROTATION_0); animator.setAnimationEndCallback(() -> { mPipTransitionState.setState(PipTransitionState.EXITED_PIP); Loading Loading @@ -631,6 +614,7 @@ public class PipTransition extends PipTransitionController implements // private void finishInner() { finishTransition(null /* tx */); if (mPipTransitionState.getSwipePipToHomeOverlay() != null) { startOverlayFadeoutAnimation(); } else if (mPipTransitionState.getState() == PipTransitionState.ENTERING_PIP) { Loading @@ -652,6 +636,7 @@ public class PipTransition extends PipTransitionController implements } if (mFinishCallback != null) { mFinishCallback.onTransitionFinished(wct); mFinishCallback = null; } } Loading