diff options
| author | 2022-09-15 06:59:12 +0000 | |
|---|---|---|
| committer | 2022-09-15 06:59:12 +0000 | |
| commit | ce7b20782e85fb134e5537a16b697850ab730b7c (patch) | |
| tree | 7b252fbf19868a0f6ae8824916e512075d9cdfd4 | |
| parent | 5956628e636dc6bf7d50206351f34e89503b84a5 (diff) | |
| parent | 9170b62c9c8840aa45bba467eb573a965499baad (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>
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; |