OSDN Git Service

Transitionless crashes
authorAdrian Roos <roosa@google.com>
Tue, 10 Apr 2018 21:12:10 +0000 (14:12 -0700)
committerAdrian Roos <roosa@google.com>
Tue, 17 Apr 2018 13:59:50 +0000 (15:59 +0200)
Suppresses app transitions when an activity finishes due to crashing.

Fixes: 70640329
Test: "Dev Tools" > Bad Behavior > Crash main thread, verify there's no transition.
Change-Id: I51c4b98b793794b013c266a1dee3fb2e7faf4bd7

core/java/android/view/WindowManager.java
services/core/java/com/android/server/am/ActivityStack.java
services/core/java/com/android/server/wm/AppTransition.java
services/core/java/com/android/server/wm/WindowSurfacePlacer.java

index 0f5c23f..37aca26 100644 (file)
@@ -248,6 +248,12 @@ public interface WindowManager extends ViewManager {
     int TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
 
     /**
+     * A crashing activity is being closed.
+     * @hide
+     */
+    int TRANSIT_CRASHING_ACTIVITY_CLOSE = 26;
+
+    /**
      * @hide
      */
     @IntDef(prefix = { "TRANSIT_" }, value = {
index eb482c1..e809f90 100644 (file)
@@ -91,6 +91,7 @@ import static com.android.server.am.ActivityStackProto.RESUMED_ACTIVITY;
 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;
@@ -3559,6 +3560,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
         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
@@ -4989,6 +4992,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
                             + 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");
                 }
index c6f156b..a24ac21 100644 (file)
@@ -20,6 +20,7 @@ import static android.view.WindowManager.LayoutParams;
 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 @@ public class AppTransition implements Dump {
             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 @@ public class AppTransition implements Dump {
             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);
index b85f4a4..70287db 100644 (file)
@@ -20,6 +20,7 @@ import static android.app.ActivityManagerInternal.APP_TRANSITION_SNAPSHOT;
 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 @@ class WindowSurfacePlacer {
      */
     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 @@ class WindowSurfacePlacer {
 
     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