Merge "Transitionless crashes" into pi-dev
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 0f5c23f..37aca26 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -248,6 +248,12 @@
     int TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
 
     /**
+     * A crashing activity is being closed.
+     * @hide
+     */
+    int TRANSIT_CRASHING_ACTIVITY_CLOSE = 26;
+
+    /**
      * @hide
      */
     @IntDef(prefix = { "TRANSIT_" }, value = {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index e54e645..e20356f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -91,6 +91,7 @@
 import static com.android.server.am.ActivityStackProto.TASKS;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
@@ -3555,6 +3556,8 @@
         int taskNdx = mTaskHistory.indexOf(finishedTask);
         final TaskRecord task = finishedTask;
         int activityNdx = task.mActivities.indexOf(r);
+        mWindowManager.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* TODO */,
+                0, true /* forceOverride */);
         finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
         finishedTask = task;
         // Also terminate any activities below it that aren't yet
@@ -4983,6 +4986,8 @@
                             + r.intent.getComponent().flattenToShortString());
                     // Force the destroy to skip right to removal.
                     r.app = null;
+                    mWindowManager.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE,
+                            false /* TODO */, 0, true /* forceOverride */);
                     finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false,
                             "handleAppCrashedLocked");
                 }
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c6f156b..a24ac21 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -20,6 +20,7 @@
 import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_RELAUNCH;
+import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
@@ -1569,6 +1570,8 @@
             a = null;
         } else if (transit == TRANSIT_KEYGUARD_UNOCCLUDE && !enter) {
             a = loadAnimationRes(lp, com.android.internal.R.anim.wallpaper_open_exit);
+        } else if (transit == TRANSIT_CRASHING_ACTIVITY_CLOSE) {
+            a = null;
         } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
                 || transit == TRANSIT_TASK_OPEN
                 || transit == TRANSIT_TASK_TO_FRONT)) {
@@ -2157,8 +2160,10 @@
             setAppTransition(transit, flags);
         }
         // We never want to change from a Keyguard transit to a non-Keyguard transit, as our logic
-        // relies on the fact that we always execute a Keyguard transition after preparing one.
-        else if (!alwaysKeepCurrent && !isKeyguardTransit(transit)) {
+        // relies on the fact that we always execute a Keyguard transition after preparing one. We
+        // also don't want to change away from a crashing transition.
+        else if (!alwaysKeepCurrent && !isKeyguardTransit(transit)
+                && transit != TRANSIT_CRASHING_ACTIVITY_CLOSE) {
             if (transit == TRANSIT_TASK_OPEN && isTransitionEqual(TRANSIT_TASK_CLOSE)) {
                 // Opening a new task always supersedes a close for the anim.
                 setAppTransition(transit, flags);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index b85f4a4..70287db 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -20,6 +20,7 @@
 import static android.app.ActivityManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
 import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
 
+import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN;
@@ -368,6 +369,10 @@
      */
     private void overrideWithRemoteAnimationIfSet(AppWindowToken animLpToken, int transit,
             ArraySet<Integer> activityTypes) {
+        if (transit == TRANSIT_CRASHING_ACTIVITY_CLOSE) {
+            // The crash transition has higher priority than any involved remote animations.
+            return;
+        }
         if (animLpToken == null) {
             return;
         }
@@ -625,13 +630,12 @@
 
     private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
             boolean closingAppHasWallpaper) {
-        // Given no app transition pass it through instead of a wallpaper transition
-        if (transit == TRANSIT_NONE) {
-            return TRANSIT_NONE;
-        }
+        // Given no app transition pass it through instead of a wallpaper transition.
+        // Never convert the crashing transition.
         // Never update the transition for the wallpaper if we are just docking from recents
-        if (transit == TRANSIT_DOCK_TASK_FROM_RECENTS) {
-            return TRANSIT_DOCK_TASK_FROM_RECENTS;
+        if (transit == TRANSIT_NONE || transit == TRANSIT_CRASHING_ACTIVITY_CLOSE
+                || transit == TRANSIT_DOCK_TASK_FROM_RECENTS) {
+            return transit;
         }
 
         // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper