summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2022-09-15 06:59:12 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2022-09-15 06:59:12 +0000
commitce7b20782e85fb134e5537a16b697850ab730b7c (patch)
tree7b252fbf19868a0f6ae8824916e512075d9cdfd4
parent5956628e636dc6bf7d50206351f34e89503b84a5 (diff)
parent9170b62c9c8840aa45bba467eb573a965499baad (diff)
Merge "Update ActivityEmbedding split open/close animation adapter for Shell" into tm-qpr-dev am: 9170b62c9c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19863544 Change-Id: I617820339a33ca45ba08177e3374c0fca1fee64c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java100
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java12
3 files changed, 49 insertions, 89 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
index cc4db933ec9f..064c304825da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.activityembedding;
-import static android.graphics.Matrix.MSCALE_X;
import static android.graphics.Matrix.MTRANS_X;
import static android.graphics.Matrix.MTRANS_Y;
@@ -42,31 +41,45 @@ class ActivityEmbeddingAnimationAdapter {
*/
private static final int LAYER_NO_OVERRIDE = -1;
+ @NonNull
final Animation mAnimation;
+ @NonNull
final TransitionInfo.Change mChange;
+ @NonNull
final SurfaceControl mLeash;
+ /** Area in absolute coordinate that the animation surface shouldn't go beyond. */
+ @NonNull
+ private final Rect mWholeAnimationBounds = new Rect();
+ @NonNull
final Transformation mTransformation = new Transformation();
+ @NonNull
final float[] mMatrix = new float[9];
+ @NonNull
final float[] mVecs = new float[4];
+ @NonNull
final Rect mRect = new Rect();
private boolean mIsFirstFrame = true;
private int mOverrideLayer = LAYER_NO_OVERRIDE;
ActivityEmbeddingAnimationAdapter(@NonNull Animation animation,
@NonNull TransitionInfo.Change change) {
- this(animation, change, change.getLeash());
+ this(animation, change, change.getLeash(), change.getEndAbsBounds());
}
/**
* @param leash the surface to animate, which is not necessary the same as
- * {@link TransitionInfo.Change#getLeash()}, it can be a screenshot for example.
+ * {@link TransitionInfo.Change#getLeash()}, it can be a screenshot for example.
+ * @param wholeAnimationBounds area in absolute coordinate that the animation surface shouldn't
+ * go beyond.
*/
ActivityEmbeddingAnimationAdapter(@NonNull Animation animation,
- @NonNull TransitionInfo.Change change, @NonNull SurfaceControl leash) {
+ @NonNull TransitionInfo.Change change, @NonNull SurfaceControl leash,
+ @NonNull Rect wholeAnimationBounds) {
mAnimation = animation;
mChange = change;
mLeash = leash;
+ mWholeAnimationBounds.set(wholeAnimationBounds);
}
/**
@@ -96,23 +109,31 @@ class ActivityEmbeddingAnimationAdapter {
/** To be overridden by subclasses to adjust the animation surface change. */
void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
+ // Update the surface position and alpha.
final Point offset = mChange.getEndRelOffset();
mTransformation.getMatrix().postTranslate(offset.x, offset.y);
t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
t.setAlpha(mLeash, mTransformation.getAlpha());
- // Get current animation position.
+
+ // Get current surface bounds in absolute coordinate.
+ // positionX/Y are in local coordinate, so minus the local offset to get the slide amount.
final int positionX = Math.round(mMatrix[MTRANS_X]);
final int positionY = Math.round(mMatrix[MTRANS_Y]);
- // The exiting surface starts at position: Change#getEndRelOffset() and moves with
- // positionX varying. Offset our crop region by the amount we have slided so crop
- // regions stays exactly on the original container in split.
- final int cropOffsetX = offset.x - positionX;
- final int cropOffsetY = offset.y - positionY;
- final Rect cropRect = new Rect();
- cropRect.set(mChange.getEndAbsBounds());
- // Because window crop uses absolute position.
- cropRect.offsetTo(0, 0);
- cropRect.offset(cropOffsetX, cropOffsetY);
+ final Rect cropRect = new Rect(mChange.getEndAbsBounds());
+ cropRect.offset(positionX - offset.x, positionY - offset.y);
+
+ // Store the current offset of the surface top left from (0,0) in absolute coordinate.
+ final int offsetX = cropRect.left;
+ final int offsetY = cropRect.top;
+
+ // Intersect to make sure the animation happens within the whole animation bounds.
+ if (!cropRect.intersect(mWholeAnimationBounds)) {
+ // Hide the surface when it is outside of the animation area.
+ t.setAlpha(mLeash, 0);
+ }
+
+ // cropRect is in absolute coordinate, so we need to translate it to surface top left.
+ cropRect.offset(-offsetX, -offsetY);
t.setCrop(mLeash, cropRect);
}
@@ -127,53 +148,6 @@ class ActivityEmbeddingAnimationAdapter {
}
/**
- * Should be used when the {@link TransitionInfo.Change} is in split with others, and wants to
- * animate together as one. This adapter will offset the animation leash to make the animate of
- * two windows look like a single window.
- */
- static class SplitAdapter extends ActivityEmbeddingAnimationAdapter {
- private final boolean mIsLeftHalf;
- private final int mWholeAnimationWidth;
-
- /**
- * @param isLeftHalf whether this is the left half of the animation.
- * @param wholeAnimationWidth the whole animation windows width.
- */
- SplitAdapter(@NonNull Animation animation, @NonNull TransitionInfo.Change change,
- boolean isLeftHalf, int wholeAnimationWidth) {
- super(animation, change);
- mIsLeftHalf = isLeftHalf;
- mWholeAnimationWidth = wholeAnimationWidth;
- if (wholeAnimationWidth == 0) {
- throw new IllegalArgumentException("SplitAdapter must provide wholeAnimationWidth");
- }
- }
-
- @Override
- void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
- final Point offset = mChange.getEndRelOffset();
- float posX = offset.x;
- final float posY = offset.y;
- // This window is half of the whole animation window. Offset left/right to make it
- // look as one with the other half.
- mTransformation.getMatrix().getValues(mMatrix);
- final int changeWidth = mChange.getEndAbsBounds().width();
- final float scaleX = mMatrix[MSCALE_X];
- final float totalOffset = mWholeAnimationWidth * (1 - scaleX) / 2;
- final float curOffset = changeWidth * (1 - scaleX) / 2;
- final float offsetDiff = totalOffset - curOffset;
- if (mIsLeftHalf) {
- posX += offsetDiff;
- } else {
- posX -= offsetDiff;
- }
- mTransformation.getMatrix().postTranslate(posX, posY);
- t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
- t.setAlpha(mLeash, mTransformation.getAlpha());
- }
- }
-
- /**
* Should be used for the animation of the snapshot of a {@link TransitionInfo.Change} that has
* size change.
*/
@@ -181,7 +155,7 @@ class ActivityEmbeddingAnimationAdapter {
SnapshotAdapter(@NonNull Animation animation, @NonNull TransitionInfo.Change change,
@NonNull SurfaceControl snapshotLeash) {
- super(animation, change, snapshotLeash);
+ super(animation, change, snapshotLeash, change.getEndAbsBounds());
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 7e0795d11153..846d2c9b3396 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -22,7 +22,6 @@ import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
-import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.Log;
@@ -169,15 +168,12 @@ class ActivityEmbeddingAnimationRunner {
final Rect openingWholeScreenBounds = new Rect();
final Rect closingWholeScreenBounds = new Rect();
for (TransitionInfo.Change change : info.getChanges()) {
- final Rect bounds = new Rect(change.getEndAbsBounds());
- final Point offset = change.getEndRelOffset();
- bounds.offsetTo(offset.x, offset.y);
if (Transitions.isOpeningType(change.getMode())) {
openingChanges.add(change);
- openingWholeScreenBounds.union(bounds);
+ openingWholeScreenBounds.union(change.getEndAbsBounds());
} else {
closingChanges.add(change);
- closingWholeScreenBounds.union(bounds);
+ closingWholeScreenBounds.union(change.getEndAbsBounds());
}
}
@@ -210,22 +206,8 @@ class ActivityEmbeddingAnimationRunner {
@NonNull BiFunction<TransitionInfo.Change, Rect, Animation> animationProvider,
@NonNull Rect wholeAnimationBounds) {
final Animation animation = animationProvider.apply(change, wholeAnimationBounds);
- final Rect bounds = new Rect(change.getEndAbsBounds());
- final Point offset = change.getEndRelOffset();
- bounds.offsetTo(offset.x, offset.y);
- if (bounds.left == wholeAnimationBounds.left
- && bounds.right != wholeAnimationBounds.right) {
- // This is the left split of the whole animation window.
- return new ActivityEmbeddingAnimationAdapter.SplitAdapter(animation, change,
- true /* isLeftHalf */, wholeAnimationBounds.width());
- } else if (bounds.left != wholeAnimationBounds.left
- && bounds.right == wholeAnimationBounds.right) {
- // This is the right split of the whole animation window.
- return new ActivityEmbeddingAnimationAdapter.SplitAdapter(animation, change,
- false /* isLeftHalf */, wholeAnimationBounds.width());
- }
- // Open/close window that fills the whole animation.
- return new ActivityEmbeddingAnimationAdapter(animation, change);
+ return new ActivityEmbeddingAnimationAdapter(animation, change, change.getLeash(),
+ wholeAnimationBounds);
}
@NonNull
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index 6f06f28caff2..ad0dddf77002 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -185,8 +185,10 @@ class ActivityEmbeddingAnimationSpec {
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
? R.anim.task_fragment_open_enter
: R.anim.task_fragment_open_exit);
- final Rect bounds = change.getEndAbsBounds();
- animation.initialize(bounds.width(), bounds.height(),
+ // Use the whole animation bounds instead of the change bounds, so that when multiple change
+ // targets are opening at the same time, the animation applied to each will be the same.
+ // Otherwise, we may see gap between the activities that are launching together.
+ animation.initialize(wholeAnimationBounds.width(), wholeAnimationBounds.height(),
wholeAnimationBounds.width(), wholeAnimationBounds.height());
animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
return animation;
@@ -203,8 +205,10 @@ class ActivityEmbeddingAnimationSpec {
animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
? R.anim.task_fragment_close_enter
: R.anim.task_fragment_close_exit);
- final Rect bounds = change.getEndAbsBounds();
- animation.initialize(bounds.width(), bounds.height(),
+ // Use the whole animation bounds instead of the change bounds, so that when multiple change
+ // targets are closing at the same time, the animation applied to each will be the same.
+ // Otherwise, we may see gap between the activities that are finishing together.
+ animation.initialize(wholeAnimationBounds.width(), wholeAnimationBounds.height(),
wholeAnimationBounds.width(), wholeAnimationBounds.height());
animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
return animation;