summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java65
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java9
3 files changed, 67 insertions, 11 deletions
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 4640106b5f1c..9b8006362c79 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
@@ -245,8 +245,8 @@ class ActivityEmbeddingAnimationSpec {
private boolean shouldShowBackdrop(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change) {
- final Animation a = loadAttributeAnimation(info, change, WALLPAPER_TRANSITION_NONE,
- mTransitionAnimation, false);
+ final Animation a = loadAttributeAnimation(info.getType(), info, change,
+ WALLPAPER_TRANSITION_NONE, mTransitionAnimation, false);
return a != null && a.getShowBackdrop();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 7df658e6c9db..d310ae32993c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -37,8 +37,12 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
@@ -334,6 +338,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
boolean isDisplayRotationAnimationStarted = false;
final boolean isDreamTransition = isDreamTransition(info);
final boolean isOnlyTranslucent = isOnlyTranslucent(info);
+ final boolean isActivityReplace = checkActivityReplacement(info, startTransaction);
+ // Some patterns (eg. activity "replacement") require us to re-interpret the type
+ @WindowManager.TransitionType final int transitType =
+ isActivityReplace ? TRANSIT_OPEN : info.getType();
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -430,7 +438,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// Don't animate anything that isn't independent.
if (!TransitionInfo.isIndependent(change, info)) continue;
- Animation a = loadAnimation(info, change, wallpaperTransit, isDreamTransition);
+ Animation a = loadAnimation(transitType, info, change, wallpaperTransit,
+ isDreamTransition);
if (a != null) {
if (isTask) {
final boolean isTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0;
@@ -604,6 +613,53 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return (translucentOpen + translucentClose) > 0;
}
+ /**
+ * Checks for an edge-case where an activity calls finish() followed immediately by
+ * startActivity() to "replace" itself. If in this case, it will swap the layer of the
+ * close/open activities and return `true`. This way, we pretend like we are just "opening"
+ * the new activity.
+ */
+ private static boolean checkActivityReplacement(@NonNull TransitionInfo info,
+ SurfaceControl.Transaction t) {
+ if (info.getType() != TRANSIT_CLOSE) {
+ return false;
+ }
+ int closing = -1;
+ int opening = -1;
+ for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if ((change.getTaskInfo() != null || change.hasFlags(FLAG_IS_DISPLAY))
+ && !TransitionUtil.isOrderOnly(change)) {
+ // This isn't an activity-level transition.
+ return false;
+ }
+ if (change.getTaskInfo() != null
+ && change.hasFlags(FLAG_IS_DISPLAY | FLAGS_IS_NON_APP_WINDOW)) {
+ // Ignore non-activity containers.
+ continue;
+ }
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ closing = i;
+ } else if (change.getMode() == TRANSIT_OPEN) {
+ // OPEN implies that it is a new launch. If going "back" the opening app will be
+ // TO_FRONT
+ opening = i;
+ } else if (change.getMode() == TRANSIT_TO_FRONT) {
+ // Normal "going back", so not a replacement.
+ return false;
+ }
+ }
+ if (closing < 0 || opening < 0) {
+ return false;
+ }
+ // Swap the opening and closing z-orders since we're swapping the transit type.
+ final int numChanges = info.getChanges().size();
+ final int zSplitLine = numChanges + 1;
+ t.setLayer(info.getChanges().get(opening).getLeash(), zSplitLine + numChanges - opening);
+ t.setLayer(info.getChanges().get(closing).getLeash(), zSplitLine - closing);
+ return true;
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -656,12 +712,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
@Nullable
- private Animation loadAnimation(@NonNull TransitionInfo info,
+ private Animation loadAnimation(int type, @NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, int wallpaperTransit,
boolean isDreamTransition) {
Animation a;
- final int type = info.getType();
final int flags = info.getFlags();
final int changeMode = change.getMode();
final int changeFlags = change.getFlags();
@@ -716,8 +771,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// If there's a scene-transition, then jump-cut.
return null;
} else {
- a = loadAttributeAnimation(
- info, change, wallpaperTransit, mTransitionAnimation, isDreamTransition);
+ a = loadAttributeAnimation(type, info, change, wallpaperTransit, mTransitionAnimation,
+ isDreamTransition);
}
if (a != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index d978eafa97f3..7b1ce2fe6a08 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -45,6 +45,7 @@ import android.graphics.Rect;
import android.graphics.Shader;
import android.view.Surface;
import android.view.SurfaceControl;
+import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.window.ScreenCapture;
@@ -61,10 +62,10 @@ public class TransitionAnimationHelper {
/** Loads the animation that is defined through attribute id for the given transition. */
@Nullable
- public static Animation loadAttributeAnimation(@NonNull TransitionInfo info,
- @NonNull TransitionInfo.Change change, int wallpaperTransit,
- @NonNull TransitionAnimation transitionAnimation, boolean isDreamTransition) {
- final int type = info.getType();
+ public static Animation loadAttributeAnimation(@WindowManager.TransitionType int type,
+ @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change,
+ int wallpaperTransit, @NonNull TransitionAnimation transitionAnimation,
+ boolean isDreamTransition) {
final int changeMode = change.getMode();
final int changeFlags = change.getFlags();
final boolean enter = TransitionUtil.isOpeningType(changeMode);