Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java +2 −4 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.view.Choreographer; import android.view.SurfaceControl; import com.android.wm.shell.R; import com.android.wm.shell.transition.Transitions; /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition. Loading Loading @@ -180,8 +179,7 @@ public class PipSurfaceTransactionHelper { // destination are different. final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH; final Rect crop = mTmpDestinationRect; crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH : destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH); crop.set(0, 0, destW, destH); // Inverse scale for crop to fit in screen coordinates. crop.scale(1 / scale); crop.offset(insets.left, insets.top); Loading @@ -200,8 +198,8 @@ public class PipSurfaceTransactionHelper { } } mTmpTransform.setScale(scale, scale); mTmpTransform.postRotate(degrees); mTmpTransform.postTranslate(positionX, positionY); mTmpTransform.postRotate(degrees); tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setCrop(leash, crop); return this; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java +31 −15 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.pip2.animation; import static android.view.Surface.ROTATION_90; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.RectEvaluator; Loading Loading @@ -73,6 +75,7 @@ public class PipExpandAnimator extends ValueAnimator { mAnimationStartCallback.run(); } if (mStartTransaction != null) { onExpandAnimationUpdate(mStartTransaction, 0f); mStartTransaction.apply(); } } Loading @@ -81,13 +84,7 @@ public class PipExpandAnimator extends ValueAnimator { public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (mFinishTransaction != null) { // 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), false /* isInPipDirection */, 1f) .round(mFinishTransaction, mLeash, false /* applyCornerRadius */) .shadow(mFinishTransaction, mLeash, false /* applyCornerRadius */); onExpandAnimationUpdate(mFinishTransaction, 1f); } if (mAnimationEndCallback != null) { mAnimationEndCallback.run(); Loading @@ -102,14 +99,7 @@ public class PipExpandAnimator extends ValueAnimator { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final float fraction = getAnimatedFraction(); // TODO (b/350801661): implement fixed rotation Rect insets = getInsets(fraction); mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, insets, false /* isInPipDirection */, fraction) .round(tx, mLeash, false /* applyCornerRadius */) .shadow(tx, mLeash, false /* applyCornerRadius */); onExpandAnimationUpdate(tx, fraction); tx.apply(); } }; Loading Loading @@ -167,6 +157,32 @@ public class PipExpandAnimator extends ValueAnimator { mAnimationEndCallback = runnable; } private void onExpandAnimationUpdate(SurfaceControl.Transaction tx, float fraction) { Rect insets = getInsets(fraction); if (mRotation == Surface.ROTATION_0) { mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, insets, false /* isInPipDirection */, fraction); } else { // Fixed rotation case. Rect start = mStartBounds; Rect end = mEndBounds; float degrees, x, y; x = fraction * (end.left - start.left) + start.left; y = fraction * (end.top - start.top) + start.top; if (mRotation == ROTATION_90) { degrees = 90 * fraction; } else { degrees = -90 * fraction; } mPipSurfaceTransactionHelper.rotateAndScaleWithCrop(tx, mLeash, mBaseBounds, mAnimatedRect, insets, degrees, x, y, true /* isExpanding */, mRotation == ROTATION_90); } mPipSurfaceTransactionHelper.round(tx, mLeash, false /* applyCornerRadius */) .shadow(tx, mLeash, false /* applyShadowRadius */); } private Rect getInsets(float fraction) { final Rect startInsets = mSourceRectHintInsets; final Rect endInsets = mZeroInsets; Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.SurfaceControl; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.ShellExecutor; Loading @@ -36,6 +37,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip2.animation.PipResizeAnimator; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.annotations.ShellMainThread; import java.util.ArrayList; Loading Loading @@ -121,6 +123,9 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, if (mPictureInPictureParams.equals(params)) { return; } ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "onTaskInfoChanged: %s, state=%s oldParams=%s newParams=%s", taskInfo.topActivity, mPipTransitionState, mPictureInPictureParams, params); setPictureInPictureParams(params); float newAspectRatio = mPictureInPictureParams.getAspectRatioFloat(); if (PipUtils.aspectRatioChanged(newAspectRatio, mPipBoundsState.getAspectRatio())) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +69 −26 Original line number Diff line number Diff line Loading @@ -325,9 +325,7 @@ public class PipTransition extends PipTransitionController implements return false; } SurfaceControl pipLeash = pipChange.getLeash(); Preconditions.checkNotNull(pipLeash, "Leash is null for swipe-up transition."); final SurfaceControl pipLeash = getLeash(pipChange); final Rect destinationBounds = pipChange.getEndAbsBounds(); final SurfaceControl swipePipToHomeOverlay = mPipTransitionState.getSwipePipToHomeOverlay(); if (swipePipToHomeOverlay != null) { Loading @@ -349,7 +347,7 @@ public class PipTransition extends PipTransitionController implements : startRotation - endRotation; if (delta != ROTATION_0) { mPipTransitionState.setInFixedRotation(true); handleBoundsTypeFixedRotation(pipChange, pipActivityChange, endRotation); handleBoundsEnterFixedRotation(pipChange, pipActivityChange, endRotation); } prepareConfigAtEndActivity(startTransaction, finishTransaction, pipChange, Loading Loading @@ -414,15 +412,15 @@ public class PipTransition extends PipTransitionController implements } final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info); int startRotation = pipChange.getStartRotation(); int endRotation = fixedRotationChange != null final int startRotation = pipChange.getStartRotation(); final int endRotation = fixedRotationChange != null ? fixedRotationChange.getEndFixedRotation() : ROTATION_UNDEFINED; final int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0 : startRotation - endRotation; if (delta != ROTATION_0) { mPipTransitionState.setInFixedRotation(true); handleBoundsTypeFixedRotation(pipChange, pipActivityChange, handleBoundsEnterFixedRotation(pipChange, pipActivityChange, fixedRotationChange.getEndFixedRotation()); } Loading Loading @@ -459,7 +457,7 @@ public class PipTransition extends PipTransitionController implements animator.start(); } private void handleBoundsTypeFixedRotation(TransitionInfo.Change pipTaskChange, private void handleBoundsEnterFixedRotation(TransitionInfo.Change pipTaskChange, TransitionInfo.Change pipActivityChange, int endRotation) { final Rect endBounds = pipTaskChange.getEndAbsBounds(); final Rect endActivityBounds = pipActivityChange.getEndAbsBounds(); Loading Loading @@ -492,6 +490,26 @@ public class PipTransition extends PipTransitionController implements endBounds.top + activityEndOffset.y); } private void handleExpandFixedRotation(TransitionInfo.Change pipTaskChange, int endRotation) { final Rect endBounds = pipTaskChange.getEndAbsBounds(); final int width = endBounds.width(); final int height = endBounds.height(); final int left = endBounds.left; final int top = endBounds.top; int newTop, newLeft; if (endRotation == Surface.ROTATION_90) { newLeft = top; newTop = -(left + width); } else { newLeft = -(height + top); newTop = left; } // Modify the endBounds, rotating and placing them potentially off-screen, so that // as we translate and rotate around the origin, we place them right into the target. endBounds.set(newLeft, newTop, newLeft + height, newTop + width); } private boolean startAlphaTypeEnterAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, Loading Loading @@ -544,33 +562,51 @@ public class PipTransition extends PipTransitionController implements } } // for multi activity, we need to manually set the leash layer if (pipChange.getTaskInfo() == null) { TransitionInfo.Change parent = getChangeByToken(info, pipChange.getParent()); if (parent != null) { startTransaction.setLayer(parent.getLeash(), Integer.MAX_VALUE - 1); } // The parent change if we were in a multi-activity PiP; null if single activity PiP. final TransitionInfo.Change parentBeforePip = pipChange.getTaskInfo() == null ? getChangeByToken(info, pipChange.getParent()) : null; if (parentBeforePip != null) { // For multi activity, we need to manually set the leash layer startTransaction.setLayer(parentBeforePip.getLeash(), Integer.MAX_VALUE - 1); } Rect startBounds = pipChange.getStartAbsBounds(); Rect endBounds = pipChange.getEndAbsBounds(); SurfaceControl pipLeash = pipChange.getLeash(); Preconditions.checkNotNull(pipLeash, "Leash is null for exit transition."); final Rect startBounds = pipChange.getStartAbsBounds(); final Rect endBounds = pipChange.getEndAbsBounds(); final SurfaceControl pipLeash = getLeash(pipChange); Rect sourceRectHint = null; if (pipChange.getTaskInfo() != null && pipChange.getTaskInfo().pictureInPictureParams != null) { PictureInPictureParams params = null; if (pipChange.getTaskInfo() != null) { // single activity sourceRectHint = pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint(); } else if (mPipTaskListener.getPictureInPictureParams().hasSourceBoundsHint()) { params = pipChange.getTaskInfo().pictureInPictureParams; } else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) { // multi activity sourceRectHint = mPipTaskListener.getPictureInPictureParams().getSourceRectHint(); params = parentBeforePip.getTaskInfo().pictureInPictureParams; } final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds, startBounds); final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info); final int startRotation = pipChange.getStartRotation(); final int endRotation = fixedRotationChange != null ? fixedRotationChange.getEndFixedRotation() : ROTATION_UNDEFINED; final int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0 : endRotation - startRotation; if (delta != ROTATION_0) { handleExpandFixedRotation(pipChange, endRotation); } PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, Surface.ROTATION_0); animator.setAnimationEndCallback(this::finishTransition); sourceRectHint, delta); animator.setAnimationEndCallback(() -> { if (parentBeforePip != null) { // TODO b/377362511: Animate local leash instead to also handle letterbox case. // For multi-activity, set the crop to be null finishTransaction.setCrop(pipLeash, null); } finishTransition(); }); animator.start(); return true; } Loading Loading @@ -717,6 +753,13 @@ public class PipTransition extends PipTransitionController implements } } @NonNull private SurfaceControl getLeash(TransitionInfo.Change change) { SurfaceControl leash = change.getLeash(); Preconditions.checkNotNull(leash, "Leash is null for change=" + change); return leash; } // // Miscellaneous callbacks and listeners // Loading services/core/java/com/android/server/wm/WindowToken.java +6 −0 Original line number Diff line number Diff line Loading @@ -614,6 +614,12 @@ class WindowToken extends WindowContainer<WindowState> { final int rotation = getRelativeDisplayRotation(); if (rotation == Surface.ROTATION_0) return mFixedRotationTransformLeash; if (mFixedRotationTransformLeash != null) return mFixedRotationTransformLeash; if (ActivityTaskManagerService.isPip2ExperimentEnabled() && asActivityRecord() != null && mTransitionController.getWindowingModeAtStart( asActivityRecord()) == WINDOWING_MODE_PINNED) { // PiP handles fixed rotation animation in Shell, so do not create the rotation leash. return null; } final SurfaceControl leash = makeSurface().setContainerLayer() .setParent(getParentSurfaceControl()) Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/PipSurfaceTransactionHelper.java +2 −4 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.view.Choreographer; import android.view.SurfaceControl; import com.android.wm.shell.R; import com.android.wm.shell.transition.Transitions; /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition. Loading Loading @@ -180,8 +179,7 @@ public class PipSurfaceTransactionHelper { // destination are different. final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH; final Rect crop = mTmpDestinationRect; crop.set(0, 0, Transitions.SHELL_TRANSITIONS_ROTATION ? destH : destW, Transitions.SHELL_TRANSITIONS_ROTATION ? destW : destH); crop.set(0, 0, destW, destH); // Inverse scale for crop to fit in screen coordinates. crop.scale(1 / scale); crop.offset(insets.left, insets.top); Loading @@ -200,8 +198,8 @@ public class PipSurfaceTransactionHelper { } } mTmpTransform.setScale(scale, scale); mTmpTransform.postRotate(degrees); mTmpTransform.postTranslate(positionX, positionY); mTmpTransform.postRotate(degrees); tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setCrop(leash, crop); return this; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipExpandAnimator.java +31 −15 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.pip2.animation; import static android.view.Surface.ROTATION_90; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.RectEvaluator; Loading Loading @@ -73,6 +75,7 @@ public class PipExpandAnimator extends ValueAnimator { mAnimationStartCallback.run(); } if (mStartTransaction != null) { onExpandAnimationUpdate(mStartTransaction, 0f); mStartTransaction.apply(); } } Loading @@ -81,13 +84,7 @@ public class PipExpandAnimator extends ValueAnimator { public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (mFinishTransaction != null) { // 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), false /* isInPipDirection */, 1f) .round(mFinishTransaction, mLeash, false /* applyCornerRadius */) .shadow(mFinishTransaction, mLeash, false /* applyCornerRadius */); onExpandAnimationUpdate(mFinishTransaction, 1f); } if (mAnimationEndCallback != null) { mAnimationEndCallback.run(); Loading @@ -102,14 +99,7 @@ public class PipExpandAnimator extends ValueAnimator { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); final float fraction = getAnimatedFraction(); // TODO (b/350801661): implement fixed rotation Rect insets = getInsets(fraction); mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, insets, false /* isInPipDirection */, fraction) .round(tx, mLeash, false /* applyCornerRadius */) .shadow(tx, mLeash, false /* applyCornerRadius */); onExpandAnimationUpdate(tx, fraction); tx.apply(); } }; Loading Loading @@ -167,6 +157,32 @@ public class PipExpandAnimator extends ValueAnimator { mAnimationEndCallback = runnable; } private void onExpandAnimationUpdate(SurfaceControl.Transaction tx, float fraction) { Rect insets = getInsets(fraction); if (mRotation == Surface.ROTATION_0) { mPipSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mBaseBounds, mAnimatedRect, insets, false /* isInPipDirection */, fraction); } else { // Fixed rotation case. Rect start = mStartBounds; Rect end = mEndBounds; float degrees, x, y; x = fraction * (end.left - start.left) + start.left; y = fraction * (end.top - start.top) + start.top; if (mRotation == ROTATION_90) { degrees = 90 * fraction; } else { degrees = -90 * fraction; } mPipSurfaceTransactionHelper.rotateAndScaleWithCrop(tx, mLeash, mBaseBounds, mAnimatedRect, insets, degrees, x, y, true /* isExpanding */, mRotation == ROTATION_90); } mPipSurfaceTransactionHelper.round(tx, mLeash, false /* applyCornerRadius */) .shadow(tx, mLeash, false /* applyShadowRadius */); } private Rect getInsets(float fraction) { final Rect startInsets = mSourceRectHintInsets; final Rect endInsets = mZeroInsets; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java +5 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.SurfaceControl; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.Preconditions; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.ShellExecutor; Loading @@ -36,6 +37,7 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm; import com.android.wm.shell.common.pip.PipBoundsState; import com.android.wm.shell.common.pip.PipUtils; import com.android.wm.shell.pip2.animation.PipResizeAnimator; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.annotations.ShellMainThread; import java.util.ArrayList; Loading Loading @@ -121,6 +123,9 @@ public class PipTaskListener implements ShellTaskOrganizer.TaskListener, if (mPictureInPictureParams.equals(params)) { return; } ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "onTaskInfoChanged: %s, state=%s oldParams=%s newParams=%s", taskInfo.topActivity, mPipTransitionState, mPictureInPictureParams, params); setPictureInPictureParams(params); float newAspectRatio = mPictureInPictureParams.getAspectRatioFloat(); if (PipUtils.aspectRatioChanged(newAspectRatio, mPipBoundsState.getAspectRatio())) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +69 −26 Original line number Diff line number Diff line Loading @@ -325,9 +325,7 @@ public class PipTransition extends PipTransitionController implements return false; } SurfaceControl pipLeash = pipChange.getLeash(); Preconditions.checkNotNull(pipLeash, "Leash is null for swipe-up transition."); final SurfaceControl pipLeash = getLeash(pipChange); final Rect destinationBounds = pipChange.getEndAbsBounds(); final SurfaceControl swipePipToHomeOverlay = mPipTransitionState.getSwipePipToHomeOverlay(); if (swipePipToHomeOverlay != null) { Loading @@ -349,7 +347,7 @@ public class PipTransition extends PipTransitionController implements : startRotation - endRotation; if (delta != ROTATION_0) { mPipTransitionState.setInFixedRotation(true); handleBoundsTypeFixedRotation(pipChange, pipActivityChange, endRotation); handleBoundsEnterFixedRotation(pipChange, pipActivityChange, endRotation); } prepareConfigAtEndActivity(startTransaction, finishTransaction, pipChange, Loading Loading @@ -414,15 +412,15 @@ public class PipTransition extends PipTransitionController implements } final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info); int startRotation = pipChange.getStartRotation(); int endRotation = fixedRotationChange != null final int startRotation = pipChange.getStartRotation(); final int endRotation = fixedRotationChange != null ? fixedRotationChange.getEndFixedRotation() : ROTATION_UNDEFINED; final int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0 : startRotation - endRotation; if (delta != ROTATION_0) { mPipTransitionState.setInFixedRotation(true); handleBoundsTypeFixedRotation(pipChange, pipActivityChange, handleBoundsEnterFixedRotation(pipChange, pipActivityChange, fixedRotationChange.getEndFixedRotation()); } Loading Loading @@ -459,7 +457,7 @@ public class PipTransition extends PipTransitionController implements animator.start(); } private void handleBoundsTypeFixedRotation(TransitionInfo.Change pipTaskChange, private void handleBoundsEnterFixedRotation(TransitionInfo.Change pipTaskChange, TransitionInfo.Change pipActivityChange, int endRotation) { final Rect endBounds = pipTaskChange.getEndAbsBounds(); final Rect endActivityBounds = pipActivityChange.getEndAbsBounds(); Loading Loading @@ -492,6 +490,26 @@ public class PipTransition extends PipTransitionController implements endBounds.top + activityEndOffset.y); } private void handleExpandFixedRotation(TransitionInfo.Change pipTaskChange, int endRotation) { final Rect endBounds = pipTaskChange.getEndAbsBounds(); final int width = endBounds.width(); final int height = endBounds.height(); final int left = endBounds.left; final int top = endBounds.top; int newTop, newLeft; if (endRotation == Surface.ROTATION_90) { newLeft = top; newTop = -(left + width); } else { newLeft = -(height + top); newTop = left; } // Modify the endBounds, rotating and placing them potentially off-screen, so that // as we translate and rotate around the origin, we place them right into the target. endBounds.set(newLeft, newTop, newLeft + height, newTop + width); } private boolean startAlphaTypeEnterAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, Loading Loading @@ -544,33 +562,51 @@ public class PipTransition extends PipTransitionController implements } } // for multi activity, we need to manually set the leash layer if (pipChange.getTaskInfo() == null) { TransitionInfo.Change parent = getChangeByToken(info, pipChange.getParent()); if (parent != null) { startTransaction.setLayer(parent.getLeash(), Integer.MAX_VALUE - 1); } // The parent change if we were in a multi-activity PiP; null if single activity PiP. final TransitionInfo.Change parentBeforePip = pipChange.getTaskInfo() == null ? getChangeByToken(info, pipChange.getParent()) : null; if (parentBeforePip != null) { // For multi activity, we need to manually set the leash layer startTransaction.setLayer(parentBeforePip.getLeash(), Integer.MAX_VALUE - 1); } Rect startBounds = pipChange.getStartAbsBounds(); Rect endBounds = pipChange.getEndAbsBounds(); SurfaceControl pipLeash = pipChange.getLeash(); Preconditions.checkNotNull(pipLeash, "Leash is null for exit transition."); final Rect startBounds = pipChange.getStartAbsBounds(); final Rect endBounds = pipChange.getEndAbsBounds(); final SurfaceControl pipLeash = getLeash(pipChange); Rect sourceRectHint = null; if (pipChange.getTaskInfo() != null && pipChange.getTaskInfo().pictureInPictureParams != null) { PictureInPictureParams params = null; if (pipChange.getTaskInfo() != null) { // single activity sourceRectHint = pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint(); } else if (mPipTaskListener.getPictureInPictureParams().hasSourceBoundsHint()) { params = pipChange.getTaskInfo().pictureInPictureParams; } else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) { // multi activity sourceRectHint = mPipTaskListener.getPictureInPictureParams().getSourceRectHint(); params = parentBeforePip.getTaskInfo().pictureInPictureParams; } final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds, startBounds); final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info); final int startRotation = pipChange.getStartRotation(); final int endRotation = fixedRotationChange != null ? fixedRotationChange.getEndFixedRotation() : ROTATION_UNDEFINED; final int delta = endRotation == ROTATION_UNDEFINED ? ROTATION_0 : endRotation - startRotation; if (delta != ROTATION_0) { handleExpandFixedRotation(pipChange, endRotation); } PipExpandAnimator animator = new PipExpandAnimator(mContext, pipLeash, startTransaction, finishTransaction, endBounds, startBounds, endBounds, sourceRectHint, Surface.ROTATION_0); animator.setAnimationEndCallback(this::finishTransition); sourceRectHint, delta); animator.setAnimationEndCallback(() -> { if (parentBeforePip != null) { // TODO b/377362511: Animate local leash instead to also handle letterbox case. // For multi-activity, set the crop to be null finishTransaction.setCrop(pipLeash, null); } finishTransition(); }); animator.start(); return true; } Loading Loading @@ -717,6 +753,13 @@ public class PipTransition extends PipTransitionController implements } } @NonNull private SurfaceControl getLeash(TransitionInfo.Change change) { SurfaceControl leash = change.getLeash(); Preconditions.checkNotNull(leash, "Leash is null for change=" + change); return leash; } // // Miscellaneous callbacks and listeners // Loading
services/core/java/com/android/server/wm/WindowToken.java +6 −0 Original line number Diff line number Diff line Loading @@ -614,6 +614,12 @@ class WindowToken extends WindowContainer<WindowState> { final int rotation = getRelativeDisplayRotation(); if (rotation == Surface.ROTATION_0) return mFixedRotationTransformLeash; if (mFixedRotationTransformLeash != null) return mFixedRotationTransformLeash; if (ActivityTaskManagerService.isPip2ExperimentEnabled() && asActivityRecord() != null && mTransitionController.getWindowingModeAtStart( asActivityRecord()) == WINDOWING_MODE_PINNED) { // PiP handles fixed rotation animation in Shell, so do not create the rotation leash. return null; } final SurfaceControl leash = makeSurface().setContainerLayer() .setParent(getParentSurfaceControl()) Loading