Fix unnecessary and harmful task movement.

Changing the focus to a new activity should not move it to the top of
the task stack. When the previous activity fully pauses and the new
focused activity resumes then it will be brought to the top of the
task stack at the proper time. Moving it there prematurely causes the
ActivityManager and WindowManager stack sequences to be out of sync.

Fixes bug 9518153.

Also remove false warnings in validateTopActivitiesLocked() and add
debug for task movement to TaskStack.

Change-Id: Ib57500b07ded97223155cda7ef603aecc9b642c3
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index a4fd7ad..4f30558 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2170,29 +2170,31 @@
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             final ActivityStack stack = mStacks.get(stackNdx);
             final ActivityRecord r = stack.topRunningActivityLocked(null);
+            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
             if (isFrontStack(stack)) {
                 if (r == null) {
                     Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
                 } else {
-                    if (stack.mPausingActivity != null) {
+                    final ActivityRecord pausing = stack.mPausingActivity;
+                    if (pausing != null && pausing == r) {
                         Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
-                            " state=" + r.state);
+                            " state=" + state);
                     }
-                    if (r.state != ActivityState.INITIALIZING &&
-                            r.state != ActivityState.RESUMED) {
+                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
                         Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
-                                " state=" + r.state);
+                                " state=" + state);
                     }
                 }
             } else {
-                if (stack.mResumedActivity != null) {
+                final ActivityRecord resumed = stack.mResumedActivity;
+                if (resumed != null && resumed == r) {
                     Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
-                        " state=" + r.state);
+                        " state=" + state);
                 }
-                if (r != null && (r.state == ActivityState.INITIALIZING
-                        || r.state == ActivityState.RESUMED)) {
+                if (r != null && (state == ActivityState.INITIALIZING
+                        || state == ActivityState.RESUMED)) {
                     Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
-                            " state=" + r.state);
+                            " state=" + state);
                 }
             }
         }
diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/java/com/android/server/wm/TaskStack.java
index 827958d..b43a7a1 100644
--- a/services/java/com/android/server/wm/TaskStack.java
+++ b/services/java/com/android/server/wm/TaskStack.java
@@ -16,7 +16,12 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.TAG;
+
 import android.graphics.Rect;
+import android.os.Debug;
+import android.util.Slog;
 import android.util.TypedValue;
 
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
@@ -88,6 +93,7 @@
      * @param toTop Whether to add it to the top or bottom.
      */
     boolean addTask(Task task, boolean toTop) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop);
         mStackBox.makeDirty();
         mTasks.add(toTop ? mTasks.size() : 0, task);
         task.mStack = this;
@@ -95,11 +101,14 @@
     }
 
     boolean moveTaskToTop(Task task) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
+                + Debug.getCallers(6));
         mTasks.remove(task);
         return addTask(task, true);
     }
 
     boolean moveTaskToBottom(Task task) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
         mTasks.remove(task);
         return addTask(task, false);
     }
@@ -110,6 +119,7 @@
      * @param task The Task to delete.
      */
     void removeTask(Task task) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
         mStackBox.makeDirty();
         mTasks.remove(task);
     }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index fd06535..65a0523 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3776,7 +3776,6 @@
                 }
                 changed = mFocusedApp != newFocus;
                 mFocusedApp = newFocus;
-                moveTaskToTop(newFocus.groupId);
                 if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
                         + " moveFocusNow=" + moveFocusNow);
                 if (changed) {