summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java71
4 files changed, 73 insertions, 48 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index 579a7943829e..a09720dd6a70 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -22,6 +22,7 @@ import android.app.WindowConfiguration
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
+import android.graphics.Rect
import android.os.RemoteException
import android.os.SystemProperties
import android.util.DisplayMetrics
@@ -138,6 +139,30 @@ object PipUtils {
}
}
+
+ /**
+ * Returns a fake source rect hint for animation purposes when app-provided one is invalid.
+ * Resulting adjusted source rect hint lets the app icon in the content overlay to stay visible.
+ */
+ @JvmStatic
+ fun getEnterPipWithOverlaySrcRectHint(appBounds: Rect, aspectRatio: Float): Rect {
+ val appBoundsAspRatio = appBounds.width().toFloat() / appBounds.height()
+ val width: Int
+ val height: Int
+ var left = 0
+ var top = 0
+ if (appBoundsAspRatio < aspectRatio) {
+ width = appBounds.width()
+ height = Math.round(width / aspectRatio)
+ top = (appBounds.height() - height) / 2
+ } else {
+ height = appBounds.height()
+ width = Math.round(height * aspectRatio)
+ left = (appBounds.width() - width) / 2
+ }
+ return Rect(left, top, left + width, top + height)
+ }
+
private var isPip2ExperimentEnabled: Boolean? = null
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 57c07323d1bb..0a3c15b6057f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -40,6 +40,7 @@ import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.internal.protolog.common.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.animation.Interpolators;
+import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;
@@ -619,19 +620,8 @@ public class PipAnimationController {
// This is done for entering case only.
if (isInPipDirection(direction)) {
final float aspectRatio = endValue.width() / (float) endValue.height();
- if ((startValue.width() / (float) startValue.height()) > aspectRatio) {
- // use the full height.
- adjustedSourceRectHint.set(0, 0,
- (int) (startValue.height() * aspectRatio), startValue.height());
- adjustedSourceRectHint.offset(
- (startValue.width() - adjustedSourceRectHint.width()) / 2, 0);
- } else {
- // use the full width.
- adjustedSourceRectHint.set(0, 0,
- startValue.width(), (int) (startValue.width() / aspectRatio));
- adjustedSourceRectHint.offset(
- 0, (startValue.height() - adjustedSourceRectHint.height()) / 2);
- }
+ adjustedSourceRectHint.set(PipUtils.getEnterPipWithOverlaySrcRectHint(
+ startValue, aspectRatio));
}
} else {
adjustedSourceRectHint.set(sourceRectHint);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java
index 3e298e530415..895c2aeba9ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java
@@ -19,11 +19,13 @@ package com.android.wm.shell.pip2.animation;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
+import android.content.Context;
import android.view.SurfaceControl;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.wm.shell.R;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import java.lang.annotation.Retention;
@@ -45,6 +47,7 @@ public class PipAlphaAnimator extends ValueAnimator implements ValueAnimator.Ani
public static final int FADE_IN = 0;
public static final int FADE_OUT = 1;
+ private final int mEnterAnimationDuration;
private final SurfaceControl mLeash;
private final SurfaceControl.Transaction mStartTransaction;
@@ -55,7 +58,8 @@ public class PipAlphaAnimator extends ValueAnimator implements ValueAnimator.Ani
private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
- public PipAlphaAnimator(SurfaceControl leash,
+ public PipAlphaAnimator(Context context,
+ SurfaceControl leash,
SurfaceControl.Transaction tx,
@Fade int direction) {
mLeash = leash;
@@ -67,6 +71,9 @@ public class PipAlphaAnimator extends ValueAnimator implements ValueAnimator.Ani
}
mSurfaceControlTransactionFactory =
new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
+ mEnterAnimationDuration = context.getResources()
+ .getInteger(R.integer.config_pipEnterAnimationDuration);
+ setDuration(mEnterAnimationDuration);
addListener(this);
addUpdateListener(this);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 3e215d9bfa34..0b2db6cf3dd1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -293,37 +293,32 @@ public class PipTransition extends PipTransitionController implements
return false;
}
+ SurfaceControl overlayLeash = mPipTransitionState.getSwipePipToHomeOverlay();
PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams;
- Rect srcRectHint = params.getSourceRectHint();
- Rect startBounds = pipChange.getStartAbsBounds();
+
+ Rect appBounds = mPipTransitionState.getSwipePipToHomeAppBounds();
Rect destinationBounds = pipChange.getEndAbsBounds();
+ float aspectRatio = pipChange.getTaskInfo().pictureInPictureParams.getAspectRatioFloat();
+
+ // We fake the source rect hint when the one prvided by the app is invalid for
+ // the animation with an app icon overlay.
+ Rect animationSrcRectHint = overlayLeash == null ? params.getSourceRectHint()
+ : PipUtils.getEnterPipWithOverlaySrcRectHint(appBounds, aspectRatio);
+
WindowContainerTransaction finishWct = new WindowContainerTransaction();
SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
- if (PipBoundsAlgorithm.isSourceRectHintValidForEnterPip(srcRectHint, destinationBounds)) {
- final float scale = (float) destinationBounds.width() / srcRectHint.width();
- startTransaction.setWindowCrop(pipLeash, srcRectHint);
- startTransaction.setPosition(pipLeash,
- destinationBounds.left - srcRectHint.left * scale,
- destinationBounds.top - srcRectHint.top * scale);
-
- // Reset the scale in case we are in the multi-activity case.
- // TO_FRONT transition already scales down the task in single-activity case, but
- // in multi-activity case, reparenting yields new reset scales coming from pinned task.
- startTransaction.setScale(pipLeash, scale, scale);
- } else {
- final float scaleX = (float) destinationBounds.width() / startBounds.width();
- final float scaleY = (float) destinationBounds.height() / startBounds.height();
+ final float scale = (float) destinationBounds.width() / animationSrcRectHint.width();
+ startTransaction.setWindowCrop(pipLeash, animationSrcRectHint);
+ startTransaction.setPosition(pipLeash,
+ destinationBounds.left - animationSrcRectHint.left * scale,
+ destinationBounds.top - animationSrcRectHint.top * scale);
+ startTransaction.setScale(pipLeash, scale, scale);
+
+ if (overlayLeash != null) {
final int overlaySize = PipContentOverlay.PipAppIconOverlay.getOverlaySize(
mPipTransitionState.getSwipePipToHomeAppBounds(), destinationBounds);
- SurfaceControl overlayLeash = mPipTransitionState.getSwipePipToHomeOverlay();
-
- startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top)
- .setScale(pipLeash, scaleX, scaleY)
- .setWindowCrop(pipLeash, startBounds)
- .reparent(overlayLeash, pipLeash)
- .setLayer(overlayLeash, Integer.MAX_VALUE);
// Overlay needs to be adjusted once a new draw comes in resetting surface transform.
tx.setScale(overlayLeash, 1f, 1f);
@@ -390,15 +385,23 @@ public class PipTransition extends PipTransitionController implements
if (pipChange == null) {
return false;
}
- // cache the PiP task token and leash
- WindowContainerToken pipTaskToken = pipChange.getContainer();
- Preconditions.checkNotNull(mPipLeash, "Leash is null for alpha transition.");
- // start transition with 0 alpha
- startTransaction.setAlpha(mPipLeash, 0f);
- PipAlphaAnimator animator = new PipAlphaAnimator(mPipLeash,
- startTransaction, PipAlphaAnimator.FADE_IN);
- animator.setAnimationEndCallback(() -> finishCallback.onTransitionFinished(null));
+ Rect destinationBounds = pipChange.getEndAbsBounds();
+ SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ Preconditions.checkNotNull(pipLeash, "Leash is null for alpha transition.");
+
+ // Start transition with 0 alpha at the entry bounds.
+ startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top)
+ .setWindowCrop(pipLeash, destinationBounds.width(), destinationBounds.height())
+ .setAlpha(pipLeash, 0f);
+
+ 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.
+ onClientDrawAtTransitionEnd();
+ });
animator.start();
return true;
@@ -480,10 +483,10 @@ public class PipTransition extends PipTransitionController implements
private boolean isLegacyEnter(@NonNull TransitionInfo info) {
TransitionInfo.Change pipChange = getPipChange(info);
- // If the only change in the changes list is a TO_FRONT mode PiP task,
+ // If the only change in the changes list is a opening type PiP task,
// then this is legacy-enter PiP.
- return pipChange != null && pipChange.getMode() == TRANSIT_TO_FRONT
- && info.getChanges().size() == 1;
+ return pipChange != null && info.getChanges().size() == 1
+ && (pipChange.getMode() == TRANSIT_TO_FRONT || pipChange.getMode() == TRANSIT_OPEN);
}
private boolean isRemovePipTransition(@NonNull TransitionInfo info) {