Merge "Do not resume activities that were launched behind" into qt-dev
am: 35885e0769
Change-Id: Ifd866c6957b3cd9cfdb979c76b42396d57984943
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index b3b6efe..d18875f 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2383,7 +2383,11 @@
r.setVisible(true);
}
if (r != starting) {
- mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */);
+ // We should not resume activities that being launched behind because these
+ // activities are actually behind other fullscreen activities, but still required
+ // to be visible (such as performing Recents animation).
+ mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
+ true /* checkConfig */);
return true;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 8f41a42..1f8b33e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -24,14 +24,18 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -107,6 +111,39 @@
}
@Test
+ public void testRestartRecentsActivity() throws Exception {
+ // Have a recents activity that is not attached to its process (ActivityRecord.app = null).
+ ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+ ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_RECENTS, true /* onTop */);
+ ActivityRecord recentActivity = new ActivityBuilder(mService).setComponent(
+ mRecentsComponent).setCreateTask(true).setStack(recentsStack).build();
+ WindowProcessController app = recentActivity.app;
+ recentActivity.app = null;
+
+ // Start an activity on top.
+ new ActivityBuilder(mService).setCreateTask(true).build().getActivityStack().moveToFront(
+ "testRestartRecentsActivity");
+
+ doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+ any() /* starting */, anyInt() /* configChanges */,
+ anyBoolean() /* preserveWindows */);
+ doReturn(app).when(mService).getProcessController(eq(recentActivity.processName), anyInt());
+ ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
+ doNothing().when(lifecycleManager).scheduleTransaction(any());
+ AppWarnings appWarnings = mService.getAppWarningsLocked();
+ spyOn(appWarnings);
+ doNothing().when(appWarnings).onStartActivity(any());
+
+ startRecentsActivity();
+
+ // Recents activity must be restarted, but not be resumed while running recents animation.
+ verify(mRootActivityContainer.mStackSupervisor).startSpecificActivityLocked(
+ eq(recentActivity), eq(false), anyBoolean());
+ assertThat(recentActivity.getState()).isEqualTo(PAUSED);
+ }
+
+ @Test
public void testSetLaunchTaskBehindOfTargetActivity() {
ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);