Each displays can have individual app transition.
Include below refectoring items to support per display AppTransition:
WMS / AM refectoring parts:
- Move AppTransition related stuff from WMS into DisplayContent.
- Move WMS.prepareAppTransition into DisplayWindowController.
- Move WMS.executeAppTransition to DisplayWindowController.
- Move ATM.isNextTransitionForward to DisplayWindowController.
- Move WMS.getPendingAppTransition to DisplayWindowController.
- Move WMS.overrideAppTransition like APIs to DisplayWindowController.
- Move ActivityRecord.applyOptionsLocked to AppContainerController.
- Support tracing all display's AppTransition status for
DisplayContent.pendingLayoutChanges & window hierachy update.
- Modify logics for AppTransition related caller parts.
- Move WindowSurfacePlacer.handleAppTransitionReadyLocked related
stuffs into added class AppTransitionController.
WM unit test parts:
- Add test case for verifying app transition state per display:
- AppTransitionTests.testAppTransitionStateForMultiDisplay
- AppTransitionTests.testCleanAppTransitionWhenTaskStackReparent
- Rename WindowSurfacePlacerTest to AppTransitionControllerTest since
the test is related handle AppTransition flow.
Bug: 111362605
Test: go/wm-smoke
Test: atest ActivityManagerTransitionSelectionTests
Test: atest ActivityManagerMultiDisplayTests
Test: atest FrameworksServicesTests for DisplayContent / AppTransition
related tests.
Change-Id: Ic1793aa794eb161bec31fda57847a6ba2ff4f84f
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java
similarity index 79%
rename from services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
rename to services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java
index 057f047..aa495f7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -36,14 +36,14 @@
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class WindowSurfacePlacerTest extends WindowTestsBase {
+public class AppTransitionControllerTest extends WindowTestsBase {
- private WindowSurfacePlacer mWindowSurfacePlacer;
+ private AppTransitionController mAppTransitionController;
@Before
public void setUp() throws Exception {
super.setUp();
- mWindowSurfacePlacer = new WindowSurfacePlacer(sWm);
+ mAppTransitionController = new AppTransitionController(sWm, mDisplayContent);
}
@Test
@@ -55,10 +55,11 @@
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
translucentOpening.setFillsParent(false);
translucentOpening.setHidden(true);
- sWm.mOpeningApps.add(behind);
- sWm.mOpeningApps.add(translucentOpening);
+ mDisplayContent.mOpeningApps.add(behind);
+ mDisplayContent.mOpeningApps.add(translucentOpening);
assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN,
- mWindowSurfacePlacer.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_OPEN));
+ mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
+ TRANSIT_TASK_OPEN));
}
}
@@ -70,9 +71,10 @@
final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
translucentClosing.setFillsParent(false);
- sWm.mClosingApps.add(translucentClosing);
+ mDisplayContent.mClosingApps.add(translucentClosing);
assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE,
- mWindowSurfacePlacer.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_CLOSE));
+ mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
+ TRANSIT_TASK_CLOSE));
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
index 3053c41..ee6fbac 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
@@ -16,22 +16,33 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
import android.content.Context;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
+import android.view.Display;
+import android.view.IApplicationToken;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,51 +54,142 @@
@SmallTest
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class AppTransitionTests {
+public class AppTransitionTests extends WindowTestsBase {
- @Rule
- public final WindowManagerServiceRule mRule = new WindowManagerServiceRule();
- private WindowManagerService mWm;
+ private DisplayContent mDc;
@Before
public void setUp() throws Exception {
+ super.setUp();
final Context context = InstrumentationRegistry.getTargetContext();
- mWm = mRule.getWindowManagerService();
+ mDc = sWm.getDefaultDisplayContentLocked();
+ // For unit test, we don't need to test performSurfacePlacement to prevent some
+ // abnormal interaction with surfaceflinger native side.
+ sWm.mRoot = spy(sWm.mRoot);
+ doNothing().when(sWm.mRoot).performSurfacePlacement(anyBoolean());
}
@Test
public void testKeyguardOverride() throws Exception {
- mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
- mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
- assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+ sWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ sWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mDc.mAppTransition.getAppTransition());
}
@Test
public void testKeyguardKeep() throws Exception {
- mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
- mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
- assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+ sWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ sWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mDc.mAppTransition.getAppTransition());
}
@Test
public void testForceOverride() throws Exception {
- mWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
- mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */,
- 0 /* flags */, true /* forceOverride */);
- assertEquals(TRANSIT_ACTIVITY_OPEN, mWm.mAppTransition.getAppTransition());
+ sWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
+ mDc.getController().prepareAppTransition(TRANSIT_ACTIVITY_OPEN,
+ false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
+ assertEquals(TRANSIT_ACTIVITY_OPEN, mDc.mAppTransition.getAppTransition());
}
@Test
public void testCrashing() throws Exception {
- mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
- mWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
- assertEquals(TRANSIT_CRASHING_ACTIVITY_CLOSE, mWm.mAppTransition.getAppTransition());
+ sWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ sWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+ assertEquals(TRANSIT_CRASHING_ACTIVITY_CLOSE, mDc.mAppTransition.getAppTransition());
}
@Test
public void testKeepKeyguard_withCrashing() throws Exception {
- mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
- mWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
- assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+ sWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ sWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+ assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mDc.mAppTransition.getAppTransition());
+ }
+
+ @Test
+ public void testAppTransitionStateForMultiDisplay() throws Exception {
+ // Create 2 displays & presume both display the state is ON for ready to display & animate.
+ final DisplayContent dc1 = createNewDisplayWithController(Display.STATE_ON);
+ final DisplayContent dc2 = createNewDisplayWithController(Display.STATE_ON);
+
+ // Create 2 app window tokens to represent 2 activity window.
+ final WindowTestUtils.TestAppWindowToken token1 = createTestAppWindowToken(dc1,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final WindowTestUtils.TestAppWindowToken token2 = createTestAppWindowToken(dc2,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+
+ // Set TestAppWindowContainerController & assign first app token state to be good to go.
+ final WindowTestUtils.TestAppWindowContainerController controller1 =
+ createAppWindowController(dc1, token1.appToken);
+ final WindowTestUtils.TestAppWindowContainerController controller2 =
+ createAppWindowController(dc1, token2.appToken);
+ controller1.setContainer(token1);
+ token1.allDrawn = true;
+ token1.startingDisplayed = true;
+ token1.startingMoved = true;
+ controller2.setContainer(token2);
+
+ // Simulate activity resume / finish flows to prepare app transition & set visibility,
+ // make sure transition is set as expected for each display.
+ dc1.getController().prepareAppTransition(TRANSIT_ACTIVITY_OPEN,
+ false /* alwaysKeepCurrent */, 0 /* flags */, false /* forceOverride */);
+ assertEquals(TRANSIT_ACTIVITY_OPEN, dc1.mAppTransition.getAppTransition());
+ dc2.getController().prepareAppTransition(TRANSIT_ACTIVITY_CLOSE,
+ false /* alwaysKeepCurrent */, 0 /* flags */, false /* forceOverride */);
+ assertEquals(TRANSIT_ACTIVITY_CLOSE, dc2.mAppTransition.getAppTransition());
+ // One activity window is visible for resuming & the other activity window is invisible
+ // for finishing in different display.
+ controller1.setVisibility(true, false);
+ controller2.setVisibility(false, false);
+
+ // Make sure each display is in animating stage.
+ assertTrue(dc1.mOpeningApps.size() > 0);
+ assertTrue(dc2.mClosingApps.size() > 0);
+ assertTrue(dc1.isAppAnimating());
+ assertTrue(dc2.isAppAnimating());
+ }
+
+ @Test
+ public void testCleanAppTransitionWhenTaskStackReparent() throws Exception {
+ // Create 2 displays & presume both display the state is ON for ready to display & animate.
+ final DisplayContent dc1 = createNewDisplayWithController(Display.STATE_ON);
+ final DisplayContent dc2 = createNewDisplayWithController(Display.STATE_ON);
+
+ final TaskStack stack1 = createTaskStackOnDisplay(dc1);
+ final Task task1 = createTaskInStack(stack1, 0 /* userId */);
+ final WindowTestUtils.TestAppWindowToken token1 =
+ WindowTestUtils.createTestAppWindowToken(dc1);
+ task1.addChild(token1, 0);
+
+ // Simulate same app is during opening / closing transition set stage.
+ dc1.mClosingApps.add(token1);
+ assertTrue(dc1.mClosingApps.size() > 0);
+
+ dc1.getController().prepareAppTransition(TRANSIT_ACTIVITY_OPEN,
+ false /* alwaysKeepCurrent */, 0 /* flags */, false /* forceOverride */);
+ assertEquals(TRANSIT_ACTIVITY_OPEN, dc1.mAppTransition.getAppTransition());
+ assertTrue(dc1.mAppTransition.isTransitionSet());
+
+ dc1.mOpeningApps.add(token1);
+ assertTrue(dc1.mOpeningApps.size() > 0);
+
+ // Move stack to another display.
+ stack1.getController().reparent(dc2.getDisplayId(), new Rect(), true);
+
+ // Verify if token are cleared from both pending transition list in former display.
+ assertFalse(dc1.mOpeningApps.contains(token1));
+ assertFalse(dc1.mOpeningApps.contains(token1));
+ }
+
+ private WindowTestUtils.TestAppWindowContainerController createAppWindowController(
+ DisplayContent dc, IApplicationToken token) {
+ return createAppWindowController(
+ new WindowTestUtils.TestTaskWindowContainerController(
+ createStackControllerOnDisplay(dc)), token);
+ }
+
+ private WindowTestUtils.TestAppWindowContainerController createAppWindowController(
+ WindowTestUtils.TestTaskWindowContainerController taskController,
+ IApplicationToken token) {
+ return new WindowTestUtils.TestAppWindowContainerController(taskController, token);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index e6e08bb..d65055c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START;
@@ -90,7 +92,7 @@
private AppTransitionListener mListener;
MockAppTransition(Context context) {
- super(context, sWm);
+ super(context, sWm, mDisplayContent);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index 7d19baa..ae92984 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -85,7 +85,7 @@
@Test
public void testRun() throws Exception {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
- sWm.mOpeningApps.add(win.mAppToken);
+ mDisplayContent.mOpeningApps.add(win.mAppToken);
try {
final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
new Point(50, 100), new Rect(50, 100, 150, 150));
@@ -113,7 +113,7 @@
finishedCaptor.getValue().onAnimationFinished();
verify(mFinishedCallback).onAnimationFinished(eq(adapter));
} finally {
- sWm.mOpeningApps.clear();
+ mDisplayContent.mOpeningApps.clear();
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
index 53a1185..cb5c1cd 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
@@ -74,7 +74,7 @@
appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
assertEquals(SCREEN_ORIENTATION_PORTRAIT, stack.getOrientation());
- sWm.mClosingApps.add(appWindowToken2);
+ mDisplayContent.mClosingApps.add(appWindowToken2);
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, stack.getOrientation());
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 3ac97027..54456fb 100644
--- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -40,50 +40,50 @@
@Before
public void setUp() throws Exception {
super.setUp();
- sWm.mUnknownAppVisibilityController.clear();
+ mDisplayContent.mUnknownAppVisibilityController.clear();
}
@Test
public void testFlow() throws Exception {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
- sWm.mUnknownAppVisibilityController.notifyLaunched(token);
- sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
- sWm.mUnknownAppVisibilityController.notifyRelayouted(token);
+ mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token);
+ mDisplayContent.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
+ mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token);
// Make sure our handler processed the message.
Thread.sleep(100);
- assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+ assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
@Test
public void testMultiple() throws Exception {
final AppWindowToken token1 = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
final AppWindowToken token2 = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
- sWm.mUnknownAppVisibilityController.notifyLaunched(token1);
- sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token1);
- sWm.mUnknownAppVisibilityController.notifyLaunched(token2);
- sWm.mUnknownAppVisibilityController.notifyRelayouted(token1);
- sWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token2);
- sWm.mUnknownAppVisibilityController.notifyRelayouted(token2);
+ mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token1);
+ mDisplayContent.mUnknownAppVisibilityController.notifyAppResumedFinished(token1);
+ mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token2);
+ mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token1);
+ mDisplayContent.mUnknownAppVisibilityController.notifyAppResumedFinished(token2);
+ mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token2);
// Make sure our handler processed the message.
Thread.sleep(100);
- assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+ assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
@Test
public void testClear() throws Exception {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
- sWm.mUnknownAppVisibilityController.notifyLaunched(token);
- sWm.mUnknownAppVisibilityController.clear();;
- assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+ mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token);
+ mDisplayContent.mUnknownAppVisibilityController.clear();;
+ assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
@Test
public void testAppRemoved() throws Exception {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
- sWm.mUnknownAppVisibilityController.notifyLaunched(token);
- sWm.mUnknownAppVisibilityController.appRemovedOrHidden(token);
- assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
+ mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token);
+ mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(token);
+ assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
index 389eba5..012c4be 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
@@ -33,6 +33,7 @@
import android.hardware.display.DisplayManagerInternal;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
+import android.view.Display;
import android.view.InputChannel;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -114,7 +115,7 @@
runnable.run();
}
return null;
- }).when(atm).notifyKeyguardFlagsChanged(any());
+ }).when(atm).notifyKeyguardFlagsChanged(any(), anyInt());
InputManagerService ims = mock(InputManagerService.class);
// InputChannel is final and can't be mocked.
@@ -142,11 +143,11 @@
mService.onInitReady();
+ final Display display = mService.mDisplayManager.getDisplay(DEFAULT_DISPLAY);
+ final DisplayWindowController dcw = new DisplayWindowController(display, mService);
// Display creation is driven by the ActivityManagerService via ActivityStackSupervisor.
// We emulate those steps here.
- mService.mRoot.createDisplayContent(
- mService.mDisplayManager.getDisplay(DEFAULT_DISPLAY),
- mock(DisplayWindowController.class));
+ mService.mRoot.createDisplayContent(display, dcw);
}
private void removeServices() {
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index d0a81b2..dcfe556 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -181,9 +181,12 @@
displayContent.removeImmediately();
}
}
+ // Remove app transition & window freeze timeout callbacks to prevent unnecessary
+ // actions after test.
+ sWm.getDefaultDisplayContentLocked().mAppTransition
+ .removeAppTransitionTimeoutCallbacks();
+ sWm.mH.removeMessages(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT);
sWm.mInputMethodTarget = null;
- sWm.mClosingApps.clear();
- sWm.mOpeningApps.clear();
}
// Wait until everything is really cleaned up.
@@ -354,6 +357,32 @@
}
}
+ /**
+ * Creates a {@link DisplayContent} with given display state and adds it to the system.
+ *
+ * Unlike {@link #createNewDisplay()} that uses a mock {@link DisplayWindowController} to
+ * initialize {@link DisplayContent}, this method used real controller object when the test
+ * need to verify its related flows.
+ *
+ * @param displayState For initializing the state of the display. See
+ * {@link Display#getState()}.
+ */
+ DisplayContent createNewDisplayWithController(int displayState) {
+ // Leverage main display info & initialize it with display state for given displayId.
+ DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.copyFrom(mDisplayInfo);
+ displayInfo.state = displayState;
+ final int displayId = sNextDisplayId++;
+ final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
+ displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
+ final DisplayWindowController dcw = new DisplayWindowController(display, sWm);
+ synchronized (sWm.mWindowMap) {
+ // Display creation is driven by DisplayWindowController via ActivityStackSupervisor.
+ // We skip those steps here.
+ return sWm.mRoot.createDisplayContent(display, dcw);
+ }
+ }
+
/** Creates a {@link com.android.server.wm.WindowTestUtils.TestWindowState} */
WindowTestUtils.TestWindowState createWindowState(WindowManager.LayoutParams attrs,
WindowToken token) {