Don't take activity options that contain remote animation

Because the client doesn't need it and it only disables the
animation WM would run in this case. The issue is that if client
is faster in onStart than the other app with pausing itself, the
client wins and then we can't apply the animations anymore.

Also add some more logging if debug logging is enabled.

Test: ActivityRecordTests
Test: Swipe home, reopen other hot app quickly
Bug: 131775822
Change-Id: Ibf7d27de365ad23721c99aeb5c5f2f884b428eb6
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 39eda04..1344727 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -120,6 +120,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
@@ -1631,6 +1632,7 @@
 
     void updateOptionsLocked(ActivityOptions options) {
         if (options != null) {
+            if (DEBUG_TRANSITION) Slog.i(TAG, "Update options for " + this);
             if (pendingOptions != null) {
                 pendingOptions.abort();
             }
@@ -1641,6 +1643,7 @@
     void applyOptionsLocked() {
         if (pendingOptions != null
                 && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
+            if (DEBUG_TRANSITION) Slog.i(TAG, "Applying options for " + this);
             applyOptionsLocked(pendingOptions, intent);
             if (task == null) {
                 clearOptionsLocked(false /* withAbort */);
@@ -1762,9 +1765,19 @@
         pendingOptions = null;
     }
 
-    ActivityOptions takeOptionsLocked() {
+    ActivityOptions takeOptionsLocked(boolean fromClient) {
+        if (DEBUG_TRANSITION) Slog.i(TAG, "Taking options for " + this + " callers="
+                + Debug.getCallers(6));
         ActivityOptions opts = pendingOptions;
-        pendingOptions = null;
+
+        // If we are trying to take activity options from the client, do not null it out if it's a
+        // remote animation as the client doesn't need it ever. This is a workaround when client is
+        // faster to take the options than we are to resume the next activity.
+        // TODO (b/132432864): Fix the root cause of these transition preparing/applying options
+        // timing somehow
+        if (!fromClient || opts == null || opts.getRemoteAnimationAdapter() == null) {
+            pendingOptions = null;
+        }
         return opts;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index fe99fd2..ba41586 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -3379,7 +3379,7 @@
 
                     canMoveOptions = false;
                     if (noOptions && topOptions == null) {
-                        topOptions = p.takeOptionsLocked();
+                        topOptions = p.takeOptionsLocked(false /* fromClient */);
                         if (topOptions != null) {
                             noOptions = false;
                         }
@@ -3418,7 +3418,7 @@
                     }
                     canMoveOptions = false;
                     if (noOptions && topOptions == null) {
-                        topOptions = p.takeOptionsLocked();
+                        topOptions = p.takeOptionsLocked(false /* fromClient */);
                         if (topOptions != null) {
                             noOptions = false;
                         }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b234bc6..682b1f8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2931,7 +2931,8 @@
             synchronized (mGlobalLock) {
                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
                 if (r != null) {
-                    final ActivityOptions activityOptions = r.takeOptionsLocked();
+                    final ActivityOptions activityOptions = r.takeOptionsLocked(
+                            true /* fromClient */);
                     return activityOptions == null ? null : activityOptions.toBundle();
                 }
                 return null;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index e053ff3..07fa64f 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1902,6 +1902,8 @@
     }
 
     void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
+        if (DEBUG_APP_TRANSITIONS) Slog.i(TAG, "Override pending remote transitionSet="
+                + isTransitionSet() + " adapter=" + remoteAnimationAdapter);
         if (isTransitionSet()) {
             clear();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 8505ec2..298b302 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -1493,7 +1493,7 @@
                     if (r.finishing) {
                         continue;
                     }
-                    ActivityOptions opts = r.takeOptionsLocked();
+                    ActivityOptions opts = r.takeOptionsLocked(false /* fromClient */);
                     if (opts != null) {
                         ret.updateOptionsLocked(opts);
                     }