OSDN Git Service

Do not move home task if Recent is not the previous top
authorLouis Chang <louischang@google.com>
Thu, 11 Oct 2018 01:22:14 +0000 (09:22 +0800)
committerLouis Chang <louischang@google.com>
Wed, 17 Oct 2018 02:45:28 +0000 (10:45 +0800)
We shouldn't move the home task to front if Recents was
not the previous top activity on the display where the
task lands.

Bug: 111363427
Test: atest ActivityStackSupervisorTests

Change-Id: I39b51d5eec897bf83b2380dd8b7947c13cc7dd57

services/core/java/com/android/server/am/ActivityStackSupervisor.java
services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java

index 8c8146c..6695fdb 100644 (file)
@@ -2304,17 +2304,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
             mUserLeaving = true;
         }
 
-        // TODO(b/111363427): The moving-to-top task may not be on the top display, so it could be
-        // different from where the prev activity stays on.
-        final ActivityRecord prev = topRunningActivityLocked();
-
-        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0
-                || (prev != null && prev.isActivityTypeRecents())) {
-            // Caller wants the home activity moved with it or the previous task is recents in which
-            // case we always return home from the task we are moving to the front.
-            currentStack.getDisplay().moveHomeStackToFront("findTaskToMoveToFront");
-        }
-
+        reason = reason + " findTaskToMoveToFront";
+        boolean reparented = false;
         if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
             final Rect bounds = options.getLaunchBounds();
             task.updateOverrideConfiguration(bounds);
@@ -2322,10 +2313,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
             ActivityStack stack = getLaunchStack(null, options, task, ON_TOP);
 
             if (stack != currentStack) {
+                moveHomeStackToFrontIfNeeded(flags, stack.getDisplay(), reason);
                 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME,
-                        "findTaskToMoveToFront");
+                        reason);
                 currentStack = stack;
-                // moveTaskToStackUncheckedLocked() should already placed the task on top,
+                reparented = true;
+                // task.reparent() should already placed the task on top,
                 // still need moveTaskToFrontLocked() below for any transition settings.
             }
             if (stack.resizeStackWithLaunchBounds()) {
@@ -2340,6 +2333,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
             }
         }
 
+        if (!reparented) {
+            moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplay(), reason);
+        }
+
         final ActivityRecord r = task.getTopActivity();
         currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
                 r == null ? null : r.appTimeTracker, reason);
@@ -2351,6 +2348,18 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                 currentStack, forceNonResizeable);
     }
 
+    private void moveHomeStackToFrontIfNeeded(int flags, ActivityDisplay display, String reason) {
+        final ActivityStack focusedStack = display.getFocusedStack();
+
+        if ((display.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+                && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0)
+                || (focusedStack != null && focusedStack.isActivityTypeRecents())) {
+            // We move home stack to front when we are on a fullscreen display and caller has
+            // requested the home activity to move with it. Or the previous stack is recents.
+            display.moveHomeStackToFront(reason);
+        }
+    }
+
     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) {
         // We use the launch bounds in the activity options is the device supports freeform
         // window management or is launching into the pinned stack.
index 81a0934..cc7a24d 100644 (file)
@@ -18,6 +18,7 @@ package com.android.server.am;
 
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
@@ -34,9 +35,11 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.contains;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -407,6 +410,57 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
     }
 
     /**
+     * Verify that home stack would be moved to front when the top activity is Recents.
+     */
+    @Test
+    public void testFindTaskToMoveToFrontWhenRecentsOnTop() throws Exception {
+        // Create stack/task on default display.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final TaskRecord targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+
+        // Create Recents on top of the display.
+        final ActivityStack stack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        new ActivityBuilder(mService).setTask(task).build();
+
+        final String reason = "findTaskToMoveToFront";
+        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
+                false);
+
+        verify(display).moveHomeStackToFront(contains(reason));
+    }
+
+    /**
+     * Verify that home stack won't be moved to front if the top activity on other display is
+     * Recents.
+     */
+    @Test
+    public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() throws Exception {
+        // Create stack/task on default display.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final TaskRecord targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+
+        // Create Recents on secondary display.
+        final TestActivityDisplay secondDisplay = addNewActivityDisplayAt(
+                ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack = secondDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        new ActivityBuilder(mService).setTask(task).build();
+
+        final String reason = "findTaskToMoveToFront";
+        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
+                false);
+
+        verify(display, never()).moveHomeStackToFront(contains(reason));
+    }
+
+    /**
      * Verify if a stack is not at the topmost position, it should be able to resume its activity if
      * the stack is the top focused.
      */