Implement launch bounds logic in Android (3/3)

This CL introduces persistence to launch bounds logic. It also wires up
the following state changes and persister:
1) freeform resizing;
2) windowing mode change;
3) display change;
4) task closing.

We may still need to persist immersive mode, but that needs further
discussion.

Changed launch bounds modifier a bit so that it won't launch tasks that
are completely out of the new display or conflict to existing tasks.

Bug: 113252871
Test: Manual tests on that freeform launch bounds are persisted across
reboots.
atest WmTests:LaunchParamsPersisterTests
atest WmTests:LaunchParamsControllerTests
atest WmTests:PersisterQueueTests
Change-Id: I20f3056735253c668c7f09c6eb5204e6a5990b1c
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index d4acb18..dc6324a 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -46,22 +46,7 @@
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
 import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+
 import static com.android.server.am.TaskRecordProto.ACTIVITIES;
 import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
 import static com.android.server.am.TaskRecordProto.BOUNDS;
@@ -75,6 +60,23 @@
 import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
 import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
 import static com.android.server.am.TaskRecordProto.STACK_ID;
+import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
+import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
+import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
 import static java.lang.Integer.MAX_VALUE;
 
 import android.annotation.IntDef;
@@ -87,6 +89,7 @@
 import android.app.ActivityTaskManager;
 import android.app.AppGlobals;
 import android.app.TaskInfo;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -550,6 +553,8 @@
             }
             mWindowContainerController.resize(kept, forced);
 
+            saveLaunchingStateIfNeeded();
+
             Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
             return kept;
         } finally {
@@ -1820,6 +1825,29 @@
             mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
         }
         // TODO: Should also take care of Pip mode changes here.
+
+        saveLaunchingStateIfNeeded();
+    }
+
+    /**
+     * Saves launching state if necessary so that we can launch the activity to its latest state.
+     * It only saves state if this task has been shown to user and it's in fullscreen or freeform
+     * mode.
+     */
+    void saveLaunchingStateIfNeeded() {
+        if (!hasBeenVisible) {
+            // Not ever visible to user.
+            return;
+        }
+
+        final int windowingMode = getWindowingMode();
+        if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+                && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
+            return;
+        }
+
+        // Saves the new state so that we can launch the activity at the same location.
+        mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
     }
 
     /** Clears passed config and fills it with new override values. */