mStacks.remove(stack);
final int insertPosition = getTopInsertPosition(stack, position);
mStacks.add(insertPosition, stack);
- mWindowContainerController.positionChildAt(stack.getWindowContainerController(),
- insertPosition);
+ // Since positionChildAt() is called during the creation process of pinned stacks,
+ // ActivityStack#getWindowContainerController() can be null. In this special case,
+ // since DisplayContest#positionStackAt() is called in TaskStack#onConfigurationChanged(),
+ // we don't have to call WindowContainerController#positionChildAt() here.
+ if (stack.getWindowContainerController() != null) {
+ mWindowContainerController.positionChildAt(stack.getWindowContainerController(),
+ insertPosition);
+ }
onStackOrderChanged();
}
@Override
public void onConfigurationChanged(Configuration newParentConfig) {
final int prevWindowingMode = getWindowingMode();
+ final boolean prevIsAlwaysOnTop = isAlwaysOnTop();
super.onConfigurationChanged(newParentConfig);
final ActivityDisplay display = getDisplay();
- if (display != null && prevWindowingMode != getWindowingMode()) {
+ if (display == null) {
+ return;
+ }
+ if (prevWindowingMode != getWindowingMode()) {
display.onStackWindowingModeChanged(this);
}
+ if (prevIsAlwaysOnTop != isAlwaysOnTop()) {
+ // Since always on top is only on when the stack is freeform or pinned, the state
+ // can be toggled when the windowing mode changes. We must make sure the stack is
+ // placed properly when always on top state changes.
+ display.positionChildAtTop(this);
+ }
}
@Override
// Ensure, when always on top is turned off for a stack, the stack is put just below all
// other always on top stacks.
assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
+ alwaysOnTopStack2.setAlwaysOnTop(true);
+
+ // Ensure always on top state changes properly when windowing mode changes.
+ alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ assertFalse(alwaysOnTopStack2.isAlwaysOnTop());
+ assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == alwaysOnTopStack);
+ alwaysOnTopStack2.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertTrue(alwaysOnTopStack2.isAlwaysOnTop());
+ assertTrue(mDefaultDisplay.getStackAbove(alwaysOnTopStack2) == pinnedStack);
}
@Test
package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
*/
@Test
public void testAlwaysOnTopStackLocation() {
- final TaskStack alwaysOnTopStack = createTaskStackOnDisplay(mDisplayContent);
+ final TaskStack alwaysOnTopStack = createStackControllerOnStackOnDisplay(
+ WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
final Task task = createTaskInStack(alwaysOnTopStack, 0 /* userId */);
alwaysOnTopStack.setAlwaysOnTop(true);
mDisplayContent.positionStackAt(POSITION_TOP, alwaysOnTopStack);
assertEquals(pinnedStack, mDisplayContent.getPinnedStack());
assertEquals(pinnedStack, mDisplayContent.getTopStack());
- final TaskStack anotherAlwaysOnTopStack = createTaskStackOnDisplay(mDisplayContent);
+ final TaskStack anotherAlwaysOnTopStack = createStackControllerOnStackOnDisplay(
+ WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
anotherAlwaysOnTopStack.setAlwaysOnTop(true);
mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack);
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
// existing alwaysOnTop stack.
assertEquals(anotherAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 1));
- final TaskStack nonAlwaysOnTopStack = createTaskStackOnDisplay(mDisplayContent);
+ final TaskStack nonAlwaysOnTopStack = createStackControllerOnStackOnDisplay(
+ WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
assertEquals(mDisplayContent, nonAlwaysOnTopStack.getDisplayContent());
topPosition = mDisplayContent.getStacks().size() - 1;
// Ensure the non-alwaysOnTop stack is put below the three alwaysOnTop stacks, but above the
anotherAlwaysOnTopStack.setAlwaysOnTop(false);
mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack);
assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
- topPosition = mDisplayContent.getStacks().size() - 1;
// Ensure, when always on top is turned off for a stack, the stack is put just below all
// other always on top stacks.
assertEquals(anotherAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 2));
+ anotherAlwaysOnTopStack.setAlwaysOnTop(true);
+
+ // Ensure always on top state changes properly when windowing mode changes.
+ anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
+ assertEquals(anotherAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 2));
+ anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
+ assertEquals(anotherAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 1));
}
/**