Protect against assumptions of an existing home stack.
Since there is no longer a guarantee that a home stack will
exist this:
- Adds a method to create a home stack if the display should have one
and it doesn't exist.
- Replaces calls to DisplayContent#getHomeStack() if those calls assumed
a home stack would exist.
Bug: 144085050
Fixes: 144085050
Test: RootActivityContainerTests
Test: DisplayContentTests
Change-Id: Iec6b5ccf66fed7777d19b61c5624bd097edb6786
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 1637370..61cf9ad 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1033,6 +1033,54 @@
assertTrue(continued[0]);
}
+ @Test
+ public void testGetOrCreateRootHomeTask_defaultDisplay() {
+ DisplayContent defaultDisplay = mWm.mRoot.getDisplayContent(DEFAULT_DISPLAY);
+
+ // Remove the current home stack if it exists so a new one can be created below.
+ ActivityStack homeTask = defaultDisplay.getRootHomeTask();
+ if (homeTask != null) {
+ defaultDisplay.removeStack(homeTask);
+ }
+ assertNull(defaultDisplay.getRootHomeTask());
+
+ assertNotNull(defaultDisplay.getOrCreateRootHomeTask());
+ }
+
+ @Test
+ public void testGetOrCreateRootHomeTask_supportedSecondaryDisplay() {
+ DisplayContent display = createNewDisplay();
+ doReturn(true).when(display).supportsSystemDecorations();
+ doReturn(false).when(display).isUntrustedVirtualDisplay();
+
+ // Remove the current home stack if it exists so a new one can be created below.
+ ActivityStack homeTask = display.getRootHomeTask();
+ if (homeTask != null) {
+ display.removeStack(homeTask);
+ }
+ assertNull(display.getRootHomeTask());
+
+ assertNotNull(display.getOrCreateRootHomeTask());
+ }
+
+ @Test
+ public void testGetOrCreateRootHomeTask_unsupportedSystemDecorations() {
+ DisplayContent display = createNewDisplay();
+ doReturn(false).when(display).supportsSystemDecorations();
+
+ assertNull(display.getRootHomeTask());
+ assertNull(display.getOrCreateRootHomeTask());
+ }
+
+ @Test
+ public void testGetOrCreateRootHomeTask_untrustedVirtualDisplay() {
+ DisplayContent display = createNewDisplay();
+ doReturn(true).when(display).isUntrustedVirtualDisplay();
+
+ assertNull(display.getRootHomeTask());
+ assertNull(display.getOrCreateRootHomeTask());
+ }
+
private boolean isOptionsPanelAtRight(int displayId) {
return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 79db927..dd46673 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -860,6 +860,26 @@
secondaryDisplay.mDisplayId, result.getDisplayId());
}
+ @Test
+ public void testSwitchUser_missingHomeRootTask() {
+ doReturn(mFullscreenStack).when(mRootWindowContainer).getTopDisplayFocusedStack();
+
+ DisplayContent defaultDisplay = mRootWindowContainer.getDefaultDisplay();
+ ActivityStack homeStack = defaultDisplay.getRootHomeTask();
+ if (homeStack != null) {
+ homeStack.removeImmediately();
+ }
+ assertNull(defaultDisplay.getRootHomeTask());
+
+ int currentUser = mRootWindowContainer.mCurrentUser;
+ int otherUser = currentUser + 1;
+
+ mRootWindowContainer.switchUser(otherUser, null);
+
+ assertNotNull(defaultDisplay.getRootHomeTask());
+ assertEquals(defaultDisplay.getTopStack(), defaultDisplay.getRootHomeTask());
+ }
+
/**
* Mock {@link RootWindowContainer#resolveHomeActivity} for returning consistent activity
* info for test cases (the original implementation will resolve from the real package manager).