Merge "Add specific z-ordering between PiP, Dream and Assistant" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2ef151d3c1
@@ -123,6 +123,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
private final RootWindowContainer.FindTaskResult
|
||||
mTmpFindTaskResult = new RootWindowContainer.FindTaskResult();
|
||||
|
||||
// Indicates whether the Assistant should show on top of the Dream (respectively, above
|
||||
// everything else on screen). Otherwise, it will be put under always-on-top stacks.
|
||||
private final boolean mAssistantOnTopOfDream;
|
||||
|
||||
/**
|
||||
* If this is the same as {@link #getFocusedStack} then the activity on the top of the focused
|
||||
* stack has been resumed. If stacks are changing position this will hold the old stack until
|
||||
@@ -148,6 +152,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
mDisplayContent = displayContent;
|
||||
mRootWindowContainer = service.mRoot;
|
||||
mAtmService = service.mAtmService;
|
||||
|
||||
mAssistantOnTopOfDream = mWmService.mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_assistantOnTopOfDream);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,56 +333,81 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
mDisplayContent.setLayoutNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a priority number to stack types. This priority defines an order between the types
|
||||
* of stacks that are added to the task display area.
|
||||
*
|
||||
* Higher priority number indicates that the stack should have a higher z-order.
|
||||
*
|
||||
* @return the priority of the stack
|
||||
*/
|
||||
private int getPriority(ActivityStack stack) {
|
||||
if (mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4;
|
||||
if (stack.isActivityTypeDream()) return 3;
|
||||
if (stack.inPinnedWindowingMode()) return 2;
|
||||
if (stack.isAlwaysOnTop()) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int findMinPositionForStack(ActivityStack stack) {
|
||||
int minPosition = POSITION_BOTTOM;
|
||||
for (int i = 0; i < mChildren.size(); ++i) {
|
||||
if (getPriority(getStackAt(i)) < getPriority(stack)) {
|
||||
minPosition = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.isAlwaysOnTop()) {
|
||||
// Since a stack could be repositioned while still being one of the children, we check
|
||||
// if this always-on-top stack already exists and if so, set the minPosition to its
|
||||
// previous position.
|
||||
final int currentIndex = getIndexOf(stack);
|
||||
if (currentIndex > minPosition) {
|
||||
minPosition = currentIndex;
|
||||
}
|
||||
}
|
||||
return minPosition;
|
||||
}
|
||||
|
||||
private int findMaxPositionForStack(ActivityStack stack) {
|
||||
for (int i = mChildren.size() - 1; i >= 0; --i) {
|
||||
final ActivityStack curr = getStackAt(i);
|
||||
// Since a stack could be repositioned while still being one of the children, we check
|
||||
// if 'curr' is the same stack and skip it if so
|
||||
final boolean sameStack = curr == stack;
|
||||
if (getPriority(curr) <= getPriority(stack) && !sameStack) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* When stack is added or repositioned, find a proper position for it.
|
||||
* This will make sure that pinned stack always stays on top.
|
||||
*
|
||||
* The order is defined as:
|
||||
* - Dream is on top of everything
|
||||
* - PiP is directly below the Dream
|
||||
* - always-on-top stacks are directly below PiP; new always-on-top stacks are added above
|
||||
* existing ones
|
||||
* - other non-always-on-top stacks come directly below always-on-top stacks; new
|
||||
* non-always-on-top stacks are added directly below always-on-top stacks and above existing
|
||||
* non-always-on-top stacks
|
||||
* - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything
|
||||
* (including the Dream); otherwise, it is a normal non-always-on-top stack
|
||||
*
|
||||
* @param requestedPosition Position requested by caller.
|
||||
* @param stack Stack to be added or positioned.
|
||||
* @param adding Flag indicates whether we're adding a new stack or positioning an existing.
|
||||
* @return The proper position for the stack.
|
||||
*/
|
||||
private int findPositionForStack(int requestedPosition, ActivityStack stack,
|
||||
boolean adding) {
|
||||
if (stack.isActivityTypeDream()) {
|
||||
return POSITION_TOP;
|
||||
}
|
||||
|
||||
if (stack.inPinnedWindowingMode()) {
|
||||
return POSITION_TOP;
|
||||
}
|
||||
|
||||
final int topChildPosition = mChildren.size() - 1;
|
||||
int belowAlwaysOnTopPosition = POSITION_BOTTOM;
|
||||
for (int i = topChildPosition; i >= 0; --i) {
|
||||
// Since a stack could be repositioned while being one of the child, return
|
||||
// current index if that's the same stack we are positioning and it is always on
|
||||
// top.
|
||||
final boolean sameStack = mChildren.get(i) == stack;
|
||||
if ((sameStack && stack.isAlwaysOnTop())
|
||||
|| (!sameStack && !mChildren.get(i).isAlwaysOnTop())) {
|
||||
belowAlwaysOnTopPosition = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private int findPositionForStack(int requestedPosition, ActivityStack stack, boolean adding) {
|
||||
// The max possible position we can insert the stack at.
|
||||
int maxPosition = POSITION_TOP;
|
||||
int maxPosition = findMaxPositionForStack(stack);
|
||||
// The min possible position we can insert the stack at.
|
||||
int minPosition = POSITION_BOTTOM;
|
||||
|
||||
if (stack.isAlwaysOnTop()) {
|
||||
if (hasPinnedTask()) {
|
||||
// Always-on-top stacks go below the pinned stack.
|
||||
maxPosition = mChildren.indexOf(mRootPinnedTask) - 1;
|
||||
}
|
||||
// Always-on-top stacks need to be above all other stacks.
|
||||
minPosition = belowAlwaysOnTopPosition
|
||||
!= POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
|
||||
} else {
|
||||
// Other stacks need to be below the always-on-top stacks.
|
||||
maxPosition = belowAlwaysOnTopPosition
|
||||
!= POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0;
|
||||
}
|
||||
int minPosition = findMinPositionForStack(stack);
|
||||
|
||||
// Cap the requested position to something reasonable for the previous position check
|
||||
// below.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
@@ -270,6 +272,28 @@ public class ActivityDisplayTests extends ActivityTestsBase {
|
||||
anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
|
||||
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
|
||||
assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1));
|
||||
|
||||
final ActivityStack dreamStack = taskDisplayArea.createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */);
|
||||
assertEquals(taskDisplayArea, dreamStack.getDisplayArea());
|
||||
assertTrue(dreamStack.isAlwaysOnTop());
|
||||
topPosition = taskDisplayArea.getStackCount() - 1;
|
||||
// Ensure dream shows above all activities, including PiP
|
||||
assertEquals(dreamStack, taskDisplayArea.getTopStack());
|
||||
assertEquals(pinnedStack, taskDisplayArea.getStackAt(topPosition - 1));
|
||||
|
||||
final ActivityStack assistStack = taskDisplayArea.createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
|
||||
assertEquals(taskDisplayArea, assistStack.getDisplayArea());
|
||||
assertFalse(assistStack.isAlwaysOnTop());
|
||||
topPosition = taskDisplayArea.getStackCount() - 1;
|
||||
|
||||
// Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream
|
||||
// is false and on top of everything when true.
|
||||
final boolean isAssistantOnTop = mContext.getResources()
|
||||
.getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream);
|
||||
assertEquals(assistStack, taskDisplayArea.getStackAt(
|
||||
isAssistantOnTop ? topPosition : topPosition - 4));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -471,23 +471,39 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
|
||||
splitScreenSecondary2.getVisibility(null /* starting */));
|
||||
|
||||
// Assistant stack shouldn't be visible behind translucent split-screen stack
|
||||
// Assistant stack shouldn't be visible behind translucent split-screen stack,
|
||||
// unless it is configured to show on top of everything.
|
||||
doReturn(false).when(assistantStack).isTranslucent(any());
|
||||
doReturn(true).when(splitScreenPrimary).isTranslucent(any());
|
||||
doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
|
||||
splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
|
||||
splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
|
||||
assertFalse(assistantStack.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
assistantStack.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_VISIBLE,
|
||||
splitScreenPrimary.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
splitScreenSecondary.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_VISIBLE,
|
||||
splitScreenSecondary2.getVisibility(null /* starting */));
|
||||
|
||||
if (isAssistantOnTop()) {
|
||||
assertTrue(assistantStack.shouldBeVisible(null /* starting */));
|
||||
assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_VISIBLE,
|
||||
assistantStack.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
splitScreenPrimary.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
splitScreenSecondary.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
splitScreenSecondary2.getVisibility(null /* starting */));
|
||||
} else {
|
||||
assertFalse(assistantStack.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
assistantStack.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_VISIBLE,
|
||||
splitScreenPrimary.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_INVISIBLE,
|
||||
splitScreenSecondary.getVisibility(null /* starting */));
|
||||
assertEquals(STACK_VISIBILITY_VISIBLE,
|
||||
splitScreenSecondary2.getVisibility(null /* starting */));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -927,9 +943,15 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
|
||||
splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
|
||||
|
||||
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
|
||||
assertFalse(assistantStack.shouldBeVisible(null /* starting */));
|
||||
if (isAssistantOnTop()) {
|
||||
assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(assistantStack.shouldBeVisible(null /* starting */));
|
||||
} else {
|
||||
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
|
||||
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
|
||||
assertFalse(assistantStack.shouldBeVisible(null /* starting */));
|
||||
}
|
||||
}
|
||||
|
||||
private ActivityStack createStandardStackForVisibilityTest(int windowingMode,
|
||||
@@ -1344,6 +1366,11 @@ public class ActivityStackTests extends ActivityTestsBase {
|
||||
anyBoolean());
|
||||
}
|
||||
|
||||
private boolean isAssistantOnTop() {
|
||||
return mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_assistantOnTopOfDream);
|
||||
}
|
||||
|
||||
private void verifyShouldSleepActivities(boolean focusedStack,
|
||||
boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
|
||||
final DisplayContent display = mock(DisplayContent.class);
|
||||
|
||||
Reference in New Issue
Block a user