Merge "Only relaunch activity on significant size configuration changes."
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5931b27..2be3bf7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -29,6 +29,7 @@
 import static com.android.internal.util.XmlUtils.writeLongAttribute;
 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
 import static com.android.server.am.ActivityManagerDebugConfig.*;
+import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -8959,17 +8960,29 @@
 
     @Override
     public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
-        synchronized(this) {
-            final long origId = Binder.clearCallingIdentity();
+        if (stackId == HOME_STACK_ID) {
+            throw new IllegalArgumentException(
+                    "moveTaskToStack: Attempt to move token " + token + " to home stack");
+        }
+        synchronized (this) {
+            long ident = Binder.clearCallingIdentity();
             try {
                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
                 if (r == null) {
                     throw new IllegalArgumentException(
                             "moveActivityToStack: No activity record matching token=" + token);
                 }
-                moveTaskToStack(r.task.taskId, stackId, true /*toTop*/);
+                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
+                        + " to stackId=" + stackId);
+                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP);
+                if (mFocusedActivity != r) {
+                    setFocusedActivityLocked(r, "moveActivityToStack");
+                } else {
+                    mStackSupervisor.setFocusedStack(r, "moveActivityToStack");
+                }
+                mStackSupervisor.resumeTopActivitiesLocked(r.task.stack, null, null);
             } finally {
-                Binder.restoreCallingIdentity(origId);
+                Binder.restoreCallingIdentity(ident);
             }
         }
     }
@@ -8979,8 +8992,8 @@
         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
                 "moveTaskToStack()");
         if (stackId == HOME_STACK_ID) {
-            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
-                    new RuntimeException("here").fillInStackTrace());
+            throw new IllegalArgumentException(
+                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
         }
         synchronized (this) {
             long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 854776a..b997926 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.HOME_STACK_ID;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
@@ -2671,21 +2672,28 @@
             ActivityRecord next = topRunningActivityLocked(null);
             final String myReason = reason + " adjustFocus";
             if (next != r) {
-                final TaskRecord task = r.task;
-                if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
-                    // For non-fullscreen stack, we want to move the focus to the next visible
-                    // stack to prevent the home screen from moving to the top and obscuring
-                    // other visible stacks.
-                    if (!mFullscreen
-                            && adjustFocusToNextVisibleStackLocked(null, myReason)) {
-                        return;
-                    }
-                    // Move the home stack to the top if this stack is fullscreen or there is no
-                    // other visible stack.
-                    if (mStackSupervisor.moveHomeStackTaskToTop(
-                            task.getTaskToReturnTo(), myReason)) {
-                        // Activity focus was already adjusted. Nothing else to do...
-                        return;
+                if (next != null && mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+                    // For freeform stack we always keep the focus within the stack as long as
+                    // there is a running activity in the stack that we can adjust focus to.
+                    mService.setFocusedActivityLocked(next, myReason);
+                    return;
+                } else {
+                    final TaskRecord task = r.task;
+                    if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
+                        // For non-fullscreen stack, we want to move the focus to the next visible
+                        // stack to prevent the home screen from moving to the top and obscuring
+                        // other visible stacks.
+                        if (!mFullscreen
+                                && adjustFocusToNextVisibleStackLocked(null, myReason)) {
+                            return;
+                        }
+                        // Move the home stack to the top if this stack is fullscreen or there is no
+                        // other visible stack.
+                        if (mStackSupervisor.moveHomeStackTaskToTop(
+                                task.getTaskToReturnTo(), myReason)) {
+                            // Activity focus was already adjusted. Nothing else to do...
+                            return;
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 3ed9270..2e9272c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -178,7 +178,7 @@
 
     // Used to indicate if an object (e.g. task) should be moved/created
     // at the top of its container (e.g. stack).
-    private static final boolean ON_TOP = true;
+    static final boolean ON_TOP = true;
 
     // Used to indicate that an objects (e.g. task) removal from its container
     // (e.g. stack) is due to it moving to another container.
@@ -2953,13 +2953,21 @@
         // Place the task in the right stack if it isn't there already based on the requested
         // bounds.
         int stackId = task.stack.mStackId;
+        final boolean wasFrontStack = isFrontStack(task.stack);
         if (bounds == null && stackId != FULLSCREEN_WORKSPACE_STACK_ID) {
             stackId = FULLSCREEN_WORKSPACE_STACK_ID;
         } else if (bounds != null && task.stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
             stackId = FREEFORM_WORKSPACE_STACK_ID;
         }
         if (stackId != task.stack.mStackId) {
-            moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, "resizeTask");
+            final String reason = "resizeTask";
+            final ActivityStack stack =
+                    moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, reason);
+            if (wasFrontStack) {
+                // Since the stack was previously in front,
+                // move the stack in which we are placing the task to the front.
+                stack.moveToFront(reason);
+            }
         }
 
         final Configuration overrideConfig = mWindowManager.resizeTask(task.taskId, bounds);