summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andrii Kulian <akulian@google.com> 2019-02-08 00:00:33 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-02-08 00:00:33 +0000
commit72a8435089720952dabe5e1c7510e28554a53923 (patch)
tree155fd1d9fa6b335cc0808f486feea6ab01b66b93
parent328c096a340761b89012fc84f0e6ec4e5361cae7 (diff)
parent0c869cc257884deafa4ce1340985663a1a2801d0 (diff)
Merge "Never resume activities that are partially occluded"
-rw-r--r--services/core/java/com/android/server/wm/ActivityDisplay.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java90
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java153
5 files changed, 255 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 62421ac4fc76..f882fdee8c1f 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -40,6 +40,7 @@ import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityDisplayProto.SINGLE_TASK_INSTANCE;
import static com.android.server.am.ActivityDisplayProto.STACKS;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
@@ -575,7 +576,8 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
final ActivityStack stack = mStacks.get(stackNdx);
final ActivityRecord resumedActivity = stack.getResumedActivity();
if (resumedActivity != null
- && (!stack.shouldBeVisible(resuming) || !stack.isFocusable())) {
+ && (stack.getVisibility(resuming) != STACK_VISIBILITY_VISIBLE
+ || !stack.isFocusable())) {
if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
" mResumedActivity=" + resumedActivity);
someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index ef4064846381..4faf910f52ea 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -109,6 +109,7 @@ import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
import static com.android.server.wm.ActivityStack.LAUNCH_TICK_MSG;
import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
@@ -2054,8 +2055,10 @@ final class ActivityRecord extends ConfigurationContainer {
* @param activeActivity the activity that is active or just completed pause action. We won't
* resume if this activity is active.
*/
- private boolean shouldResumeActivity(ActivityRecord activeActivity) {
- return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED);
+ @VisibleForTesting
+ boolean shouldResumeActivity(ActivityRecord activeActivity) {
+ return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED)
+ && getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE;
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 6f07be82d267..cc78588eeb84 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -108,6 +108,7 @@ import static com.android.server.wm.RootActivityContainer.FindTaskResult;
import static java.lang.Integer.MAX_VALUE;
+import android.annotation.IntDef;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
@@ -223,6 +224,22 @@ class ActivityStack extends ConfigurationContainer {
// How many activities have to be scheduled to stop to force a stop pass.
private static final int MAX_STOPPING_TO_FORCE = 3;
+ @IntDef(prefix = {"STACK_VISIBILITY"}, value = {
+ STACK_VISIBILITY_VISIBLE,
+ STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ STACK_VISIBILITY_INVISIBLE,
+ })
+ @interface StackVisibility {}
+
+ /** Stack is visible. No other stacks on top that fully or partially occlude it. */
+ static final int STACK_VISIBILITY_VISIBLE = 0;
+
+ /** Stack is partially occluded by other translucent stack(s) on top of it. */
+ static final int STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT = 1;
+
+ /** Stack is completely invisible. */
+ static final int STACK_VISIBILITY_INVISIBLE = 2;
+
@Override
protected int getChildCount() {
return mTaskHistory.size();
@@ -1959,14 +1976,28 @@ class ActivityStack extends ConfigurationContainer {
* @param starting The currently starting activity or null if there is none.
*/
boolean shouldBeVisible(ActivityRecord starting) {
+ return getVisibility(starting) != STACK_VISIBILITY_INVISIBLE;
+ }
+
+ /**
+ * Returns true if the stack should be visible.
+ *
+ * @param starting The currently starting activity or null if there is none.
+ */
+ @StackVisibility
+ int getVisibility(ActivityRecord starting) {
if (!isAttached() || mForceHidden) {
- return false;
+ return STACK_VISIBILITY_INVISIBLE;
}
final ActivityDisplay display = getDisplay();
boolean gotSplitScreenStack = false;
boolean gotOpaqueSplitScreenPrimary = false;
boolean gotOpaqueSplitScreenSecondary = false;
+ boolean gotTranslucentFullscreen = false;
+ boolean gotTranslucentSplitScreenPrimary = false;
+ boolean gotTranslucentSplitScreenSecondary = false;
+ boolean shouldBeVisible = true;
final int windowingMode = getWindowingMode();
final boolean isAssistantType = isActivityTypeAssistant();
for (int i = display.getChildCount() - 1; i >= 0; --i) {
@@ -1975,8 +2006,9 @@ class ActivityStack extends ConfigurationContainer {
if (other == this) {
// Should be visible if there is no other stack occluding it, unless it doesn't
// have any running activities, not starting one and not home stack.
- return hasRunningActivities || isInStackLocked(starting) != null
+ shouldBeVisible = hasRunningActivities || isInStackLocked(starting) != null
|| isActivityTypeHome();
+ break;
}
if (!hasRunningActivities) {
@@ -1996,51 +2028,79 @@ class ActivityStack extends ConfigurationContainer {
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
if (activityType == ACTIVITY_TYPE_HOME
|| (activityType == ACTIVITY_TYPE_ASSISTANT
- && mWindowManager.getRecentsAnimationController() != null)) {
- return true;
+ && mWindowManager.getRecentsAnimationController() != null)) {
+ break;
}
}
if (other.isStackTranslucent(starting)) {
// Can be visible behind a translucent fullscreen stack.
+ gotTranslucentFullscreen = true;
continue;
}
- return false;
+ return STACK_VISIBILITY_INVISIBLE;
} else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& !gotOpaqueSplitScreenPrimary) {
gotSplitScreenStack = true;
- gotOpaqueSplitScreenPrimary =
- !other.isStackTranslucent(starting);
+ gotTranslucentSplitScreenPrimary = other.isStackTranslucent(starting);
+ gotOpaqueSplitScreenPrimary = !gotTranslucentSplitScreenPrimary;
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
&& gotOpaqueSplitScreenPrimary) {
// Can not be visible behind another opaque stack in split-screen-primary mode.
- return false;
+ return STACK_VISIBILITY_INVISIBLE;
}
} else if (otherWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
&& !gotOpaqueSplitScreenSecondary) {
gotSplitScreenStack = true;
- gotOpaqueSplitScreenSecondary =
- !other.isStackTranslucent(starting);
+ gotTranslucentSplitScreenSecondary = other.isStackTranslucent(starting);
+ gotOpaqueSplitScreenSecondary = !gotTranslucentSplitScreenSecondary;
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
&& gotOpaqueSplitScreenSecondary) {
// Can not be visible behind another opaque stack in split-screen-secondary mode.
- return false;
+ return STACK_VISIBILITY_INVISIBLE;
}
}
if (gotOpaqueSplitScreenPrimary && gotOpaqueSplitScreenSecondary) {
// Can not be visible if we are in split-screen windowing mode and both halves of
// the screen are opaque.
- return false;
+ return STACK_VISIBILITY_INVISIBLE;
}
if (isAssistantType && gotSplitScreenStack) {
// Assistant stack can't be visible behind split-screen. In addition to this not
// making sense, it also works around an issue here we boost the z-order of the
// assistant window surfaces in window manager whenever it is visible.
- return false;
+ return STACK_VISIBILITY_INVISIBLE;
}
}
- // Well, nothing is stopping you from being visible...
- return true;
+ if (!shouldBeVisible) {
+ return STACK_VISIBILITY_INVISIBLE;
+ }
+
+ // Handle cases when there can be a translucent split-screen stack on top.
+ switch (windowingMode) {
+ case WINDOWING_MODE_FULLSCREEN:
+ if (gotTranslucentSplitScreenPrimary || gotTranslucentSplitScreenSecondary) {
+ // At least one of the split-screen stacks that covers this one is translucent.
+ return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+ }
+ break;
+ case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
+ if (gotTranslucentSplitScreenPrimary) {
+ // Covered by translucent primary split-screen on top.
+ return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+ }
+ break;
+ case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY:
+ if (gotTranslucentSplitScreenSecondary) {
+ // Covered by translucent secondary split-screen on top.
+ return STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+ }
+ break;
+ }
+
+ // Lastly - check if there is a translucent fullscreen stack on top.
+ return gotTranslucentFullscreen ? STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT
+ : STACK_VISIBILITY_VISIBLE;
}
final int rankTaskLayers(int baseLayer) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 192915fe903c..4073ff106592 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -24,6 +24,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
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.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM;
@@ -34,6 +35,9 @@ import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -381,6 +385,21 @@ public class ActivityRecordTests extends ActivityTestsBase {
}
@Test
+ public void testShouldResume_stackVisibility() {
+ mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
+ spyOn(mStack);
+
+ doReturn(STACK_VISIBILITY_VISIBLE).when(mStack).getVisibility(null);
+ assertEquals(true, mActivity.shouldResumeActivity(null /* activeActivity */));
+
+ doReturn(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT).when(mStack).getVisibility(null);
+ assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */));
+
+ doReturn(STACK_VISIBILITY_INVISIBLE).when(mStack).getVisibility(null);
+ assertEquals(false, mActivity.shouldResumeActivity(null /* activeActivity */));
+ }
+
+ @Test
public void testPushConfigurationWhenLaunchTaskBehind() throws Exception {
mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 986943aaf146..822700f48dd5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -37,6 +37,9 @@ import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
+import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
@@ -321,12 +324,23 @@ public class ActivityStackTests extends ActivityTestsBase {
assertFalse(homeStack.shouldBeVisible(null /* starting */));
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+ assertEquals(STACK_VISIBILITY_INVISIBLE, homeStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ splitScreenPrimary.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ splitScreenSecondary.getVisibility(null /* starting */));
// Home stack should be visible if one of the halves of split-screen is translucent.
splitScreenPrimary.setIsTranslucent(true);
assertTrue(homeStack.shouldBeVisible(null /* starting */));
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ homeStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ splitScreenPrimary.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ splitScreenSecondary.getVisibility(null /* starting */));
final TestActivityStack splitScreenSecondary2 =
createStackForShouldBeVisibleTest(mDefaultDisplay,
@@ -336,12 +350,20 @@ public class ActivityStackTests extends ActivityTestsBase {
splitScreenSecondary2.setIsTranslucent(false);
assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+ assertEquals(STACK_VISIBILITY_INVISIBLE,
+ splitScreenSecondary.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ splitScreenSecondary2.getVisibility(null /* starting */));
// First split-screen secondary should be visible behind another translucent split-screen
// secondary.
splitScreenSecondary2.setIsTranslucent(true);
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ splitScreenSecondary.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ splitScreenSecondary2.getVisibility(null /* starting */));
final TestActivityStack assistantStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
@@ -352,6 +374,14 @@ public class ActivityStackTests extends ActivityTestsBase {
assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
assertFalse(splitScreenSecondary.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 */));
// Split-screen stacks should be visible behind a translucent fullscreen stack.
assistantStack.setIsTranslucent(true);
@@ -359,6 +389,14 @@ public class ActivityStackTests extends ActivityTestsBase {
assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ assistantStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ splitScreenPrimary.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ splitScreenSecondary.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ splitScreenSecondary2.getVisibility(null /* starting */));
// Assistant stack shouldn't be visible behind translucent split-screen stack
assistantStack.setIsTranslucent(false);
@@ -369,6 +407,113 @@ public class ActivityStackTests extends ActivityTestsBase {
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
+ public void testGetVisibility_FullscreenBehindTranslucent() {
+ final TestActivityStack bottomStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+ final TestActivityStack translucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ bottomStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ translucentStack.getVisibility(null /* starting */));
+ }
+
+ @Test
+ public void testGetVisibility_FullscreenBehindTranslucentAndOpaque() {
+ final TestActivityStack bottomStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+ final TestActivityStack translucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+ final TestActivityStack opaqueStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+
+ assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_INVISIBLE,
+ translucentStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
+ }
+
+ @Test
+ public void testGetVisibility_FullscreenBehindOpaqueAndTranslucent() {
+ final TestActivityStack bottomStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+ final TestActivityStack opaqueStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+ final TestActivityStack translucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+
+ assertEquals(STACK_VISIBILITY_INVISIBLE, bottomStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ opaqueStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ translucentStack.getVisibility(null /* starting */));
+ }
+
+ @Test
+ public void testGetVisibility_FullscreenTranslucentBehindTranslucent() {
+ final TestActivityStack bottomTranslucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+ final TestActivityStack translucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ bottomTranslucentStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ translucentStack.getVisibility(null /* starting */));
+ }
+
+ @Test
+ public void testGetVisibility_FullscreenTranslucentBehindOpaque() {
+ final TestActivityStack bottomTranslucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+ final TestActivityStack opaqueStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+
+ assertEquals(STACK_VISIBILITY_INVISIBLE,
+ bottomTranslucentStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE, opaqueStack.getVisibility(null /* starting */));
+ }
+
+ @Test
+ public void testGetVisibility_FullscreenBehindTranslucentAndPip() {
+ final TestActivityStack bottomStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ false /* translucent */);
+ final TestActivityStack translucentStack =
+ createStandardStackForVisibilityTest(WINDOWING_MODE_FULLSCREEN,
+ true /* translucent */);
+ final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+ WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+ assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
+ bottomStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE,
+ translucentStack.getVisibility(null /* starting */));
+ assertEquals(STACK_VISIBILITY_VISIBLE, pinnedStack.getVisibility(null /* starting */));
}
@Test
@@ -628,6 +773,14 @@ public class ActivityStackTests extends ActivityTestsBase {
assertFalse(assistantStack.shouldBeVisible(null /* starting */));
}
+ private TestActivityStack createStandardStackForVisibilityTest(int windowingMode,
+ boolean translucent) {
+ final TestActivityStack stack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+ windowingMode, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ stack.setIsTranslucent(translucent);
+ return stack;
+ }
+
@SuppressWarnings("TypeParameterUnusedInFormals")
private <T extends ActivityStack> T createStackForShouldBeVisibleTest(
ActivityDisplay display, int windowingMode, int activityType, boolean onTop) {