Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java +13 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.wm.shell.activityembedding; import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.shouldUseSnapshotAnimationForClosingChange; import android.annotation.CallSuper; import android.graphics.Point; import android.graphics.Rect; Loading Loading @@ -97,10 +99,17 @@ class ActivityEmbeddingAnimationAdapter { final Rect startBounds = change.getStartAbsBounds(); final Rect endBounds = change.getEndAbsBounds(); mContentBounds.set(startBounds); // Put the transition to the top left for snapshot animation. if (shouldUseSnapshotAnimationForClosingChange(mChange)) { // TODO(b/275034335): Fix an issue that black hole when closing the right container // in bounds change transition. mContentRelOffset.set(0, 0); } else { mContentRelOffset.set(change.getEndRelOffset()); mContentRelOffset.offset( startBounds.left - endBounds.left, startBounds.top - endBounds.top); } } else { mContentBounds.set(change.getEndAbsBounds()); mContentRelOffset.set(change.getEndRelOffset()); Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +39 −7 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET; import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW; import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationSpec.createShowSnapshotForClosingAnimation; import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition; import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow; import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet; Loading @@ -42,6 +43,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationAdapter.SnapshotAdapter; import com.android.wm.shell.common.ScreenshotUtils; import com.android.wm.shell.util.TransitionUtil; Loading Loading @@ -185,23 +187,23 @@ class ActivityEmbeddingAnimationRunner { return createChangeAnimationAdapters(info, startTransaction); } if (TransitionUtil.isClosingType(info.getType())) { return createCloseAnimationAdapters(info); return createCloseAnimationAdapters(info, startTransaction); } return createOpenAnimationAdapters(info); return createOpenAnimationAdapters(info, startTransaction); } @NonNull private List<ActivityEmbeddingAnimationAdapter> createOpenAnimationAdapters( @NonNull TransitionInfo info) { @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) { return createOpenCloseAnimationAdapters(info, true /* isOpening */, mAnimationSpec::loadOpenAnimation); mAnimationSpec::loadOpenAnimation, startTransaction); } @NonNull private List<ActivityEmbeddingAnimationAdapter> createCloseAnimationAdapters( @NonNull TransitionInfo info) { @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) { return createOpenCloseAnimationAdapters(info, false /* isOpening */, mAnimationSpec::loadCloseAnimation); mAnimationSpec::loadCloseAnimation, startTransaction); } /** Loading @@ -211,7 +213,8 @@ class ActivityEmbeddingAnimationRunner { @NonNull private List<ActivityEmbeddingAnimationAdapter> createOpenCloseAnimationAdapters( @NonNull TransitionInfo info, boolean isOpening, @NonNull AnimationProvider animationProvider) { @NonNull AnimationProvider animationProvider, @NonNull SurfaceControl.Transaction startTransaction) { // We need to know if the change window is only a partial of the whole animation screen. // If so, we will need to adjust it to make the whole animation screen looks like one. final List<TransitionInfo.Change> openingChanges = new ArrayList<>(); Loading @@ -224,6 +227,8 @@ class ActivityEmbeddingAnimationRunner { openingWholeScreenBounds.union(change.getEndAbsBounds()); } else { closingChanges.add(change); // Also union with the start bounds because the closing transition may be shrunk. closingWholeScreenBounds.union(change.getStartAbsBounds()); closingWholeScreenBounds.union(change.getEndAbsBounds()); } } Loading @@ -241,6 +246,17 @@ class ActivityEmbeddingAnimationRunner { adapters.add(adapter); } for (TransitionInfo.Change change : closingChanges) { if (shouldUseSnapshotAnimationForClosingChange(change)) { SurfaceControl screenshot = getOrCreateScreenshot(change, change, startTransaction); if (screenshot != null) { final SnapshotAdapter snapshotAdapter = new SnapshotAdapter( createShowSnapshotForClosingAnimation(), change, screenshot); if (!isOpening) { snapshotAdapter.overrideLayer(offsetLayer++); } adapters.add(snapshotAdapter); } } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( info, change, animationProvider, closingWholeScreenBounds); if (!isOpening) { Loading @@ -251,6 +267,22 @@ class ActivityEmbeddingAnimationRunner { return adapters; } /** * Returns whether we should use snapshot animation for the closing change. * It's usually because the end bounds of the closing change are shrunk, which leaves a black * area in the transition. */ static boolean shouldUseSnapshotAnimationForClosingChange( @NonNull TransitionInfo.Change closingChange) { // Only check closing type because we only take screenshot for closing bounds-changing // changes. if (!TransitionUtil.isClosingType(closingChange.getMode())) { return false; } // Don't need to take screenshot if there's no bounds change. return !closingChange.getStartAbsBounds().equals(closingChange.getEndAbsBounds()); } /** Sets the first frame to the {@code startTransaction} to avoid any flicker on start. */ private void prepareForFirstFrame(@NonNull SurfaceControl.Transaction startTransaction, @NonNull List<ActivityEmbeddingAnimationAdapter> adapters) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +9 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,15 @@ class ActivityEmbeddingAnimationSpec { return new AlphaAnimation(alpha, alpha); } /** * Animation that intended to show snapshot for closing animation because the closing end bounds * are changed. */ @NonNull static Animation createShowSnapshotForClosingAnimation() { return new AlphaAnimation(1f, 1f); } /** Animation for window that is opening in a change transition. */ @NonNull Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java +13 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.wm.shell.activityembedding; import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.shouldUseSnapshotAnimationForClosingChange; import android.annotation.CallSuper; import android.graphics.Point; import android.graphics.Rect; Loading Loading @@ -97,10 +99,17 @@ class ActivityEmbeddingAnimationAdapter { final Rect startBounds = change.getStartAbsBounds(); final Rect endBounds = change.getEndAbsBounds(); mContentBounds.set(startBounds); // Put the transition to the top left for snapshot animation. if (shouldUseSnapshotAnimationForClosingChange(mChange)) { // TODO(b/275034335): Fix an issue that black hole when closing the right container // in bounds change transition. mContentRelOffset.set(0, 0); } else { mContentRelOffset.set(change.getEndRelOffset()); mContentRelOffset.offset( startBounds.left - endBounds.left, startBounds.top - endBounds.top); } } else { mContentBounds.set(change.getEndAbsBounds()); mContentRelOffset.set(change.getEndRelOffset()); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +39 −7 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET; import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW; import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationSpec.createShowSnapshotForClosingAnimation; import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition; import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow; import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet; Loading @@ -42,6 +43,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationAdapter.SnapshotAdapter; import com.android.wm.shell.common.ScreenshotUtils; import com.android.wm.shell.util.TransitionUtil; Loading Loading @@ -185,23 +187,23 @@ class ActivityEmbeddingAnimationRunner { return createChangeAnimationAdapters(info, startTransaction); } if (TransitionUtil.isClosingType(info.getType())) { return createCloseAnimationAdapters(info); return createCloseAnimationAdapters(info, startTransaction); } return createOpenAnimationAdapters(info); return createOpenAnimationAdapters(info, startTransaction); } @NonNull private List<ActivityEmbeddingAnimationAdapter> createOpenAnimationAdapters( @NonNull TransitionInfo info) { @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) { return createOpenCloseAnimationAdapters(info, true /* isOpening */, mAnimationSpec::loadOpenAnimation); mAnimationSpec::loadOpenAnimation, startTransaction); } @NonNull private List<ActivityEmbeddingAnimationAdapter> createCloseAnimationAdapters( @NonNull TransitionInfo info) { @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) { return createOpenCloseAnimationAdapters(info, false /* isOpening */, mAnimationSpec::loadCloseAnimation); mAnimationSpec::loadCloseAnimation, startTransaction); } /** Loading @@ -211,7 +213,8 @@ class ActivityEmbeddingAnimationRunner { @NonNull private List<ActivityEmbeddingAnimationAdapter> createOpenCloseAnimationAdapters( @NonNull TransitionInfo info, boolean isOpening, @NonNull AnimationProvider animationProvider) { @NonNull AnimationProvider animationProvider, @NonNull SurfaceControl.Transaction startTransaction) { // We need to know if the change window is only a partial of the whole animation screen. // If so, we will need to adjust it to make the whole animation screen looks like one. final List<TransitionInfo.Change> openingChanges = new ArrayList<>(); Loading @@ -224,6 +227,8 @@ class ActivityEmbeddingAnimationRunner { openingWholeScreenBounds.union(change.getEndAbsBounds()); } else { closingChanges.add(change); // Also union with the start bounds because the closing transition may be shrunk. closingWholeScreenBounds.union(change.getStartAbsBounds()); closingWholeScreenBounds.union(change.getEndAbsBounds()); } } Loading @@ -241,6 +246,17 @@ class ActivityEmbeddingAnimationRunner { adapters.add(adapter); } for (TransitionInfo.Change change : closingChanges) { if (shouldUseSnapshotAnimationForClosingChange(change)) { SurfaceControl screenshot = getOrCreateScreenshot(change, change, startTransaction); if (screenshot != null) { final SnapshotAdapter snapshotAdapter = new SnapshotAdapter( createShowSnapshotForClosingAnimation(), change, screenshot); if (!isOpening) { snapshotAdapter.overrideLayer(offsetLayer++); } adapters.add(snapshotAdapter); } } final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter( info, change, animationProvider, closingWholeScreenBounds); if (!isOpening) { Loading @@ -251,6 +267,22 @@ class ActivityEmbeddingAnimationRunner { return adapters; } /** * Returns whether we should use snapshot animation for the closing change. * It's usually because the end bounds of the closing change are shrunk, which leaves a black * area in the transition. */ static boolean shouldUseSnapshotAnimationForClosingChange( @NonNull TransitionInfo.Change closingChange) { // Only check closing type because we only take screenshot for closing bounds-changing // changes. if (!TransitionUtil.isClosingType(closingChange.getMode())) { return false; } // Don't need to take screenshot if there's no bounds change. return !closingChange.getStartAbsBounds().equals(closingChange.getEndAbsBounds()); } /** Sets the first frame to the {@code startTransaction} to avoid any flicker on start. */ private void prepareForFirstFrame(@NonNull SurfaceControl.Transaction startTransaction, @NonNull List<ActivityEmbeddingAnimationAdapter> adapters) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +9 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,15 @@ class ActivityEmbeddingAnimationSpec { return new AlphaAnimation(alpha, alpha); } /** * Animation that intended to show snapshot for closing animation because the closing end bounds * are changed. */ @NonNull static Animation createShowSnapshotForClosingAnimation() { return new AlphaAnimation(1f, 1f); } /** Animation for window that is opening in a change transition. */ @NonNull Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change, Loading