From c8b6411ed91a5937e3067a00211dc4b30585a52c Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Thu, 11 Oct 2018 09:22:14 +0800 Subject: [PATCH] Do not move home task if Recent is not the previous top 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 --- .../server/am/ActivityStackSupervisor.java | 35 +++++++----- .../am/ActivityStackSupervisorTests.java | 54 +++++++++++++++++++ 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 8c8146c54d9fd..6695fdb4b6124 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -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. diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java index 81a0934a3460f..cc7a24d5700e1 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java @@ -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; @@ -406,6 +409,57 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { assertEquals(task.getBounds(), TASK_SIZE); } + /** + * 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.