Add visibility logic for onTopLauncher.
This commit adds visibility logic to:
- force an on-top launcher to show on the top;
- determine visibility of each activity stack;
- determine visibility of each activity.
Bug: 29250513
Change-Id: Ie9d4a4ab5d2c2e0b2e44daa9d9e91c361de5e116
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index afb2c12..f973efe 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1614,6 +1614,28 @@
final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
final int focusedStackId = focusedStack.mStackId;
+ final TaskRecord topFocusedTask = focusedStack.topTask();
+ final boolean isOnTopLauncherFocused = topFocusedTask != null &&
+ topFocusedTask.isOnTopLauncher();
+ if (isOnTopLauncherFocused) {
+ // When an on-top launcher is focused, we should find out whether the freeform stack or
+ // the fullscreen stack appears first underneath and has activities to show, and then
+ // make it visible.
+ boolean behindFullscreenOrFreeForm = false;
+ for (int stackBehindFocusedIndex = mStacks.indexOf(focusedStack) - 1;
+ stackBehindFocusedIndex >= 0; stackBehindFocusedIndex--) {
+ ActivityStack stack = mStacks.get(stackBehindFocusedIndex);
+ if ((stack.mStackId == FREEFORM_WORKSPACE_STACK_ID
+ || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
+ && stack.topRunningActivityLocked() != null) {
+ if (stackIndex == stackBehindFocusedIndex) {
+ return !behindFullscreenOrFreeForm ? STACK_VISIBLE : STACK_INVISIBLE;
+ }
+ behindFullscreenOrFreeForm = true;
+ }
+ }
+ }
+
if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID
&& hasVisibleBehindActivity() && focusedStackId == HOME_STACK_ID
&& !focusedStack.topActivity().fullscreen) {
@@ -1803,7 +1825,28 @@
// status of an activity in a previous task affects other.
behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
} else if (mStackId == HOME_STACK_ID) {
- if (task.isHomeTask()) {
+ if (task.isOnTopLauncher()) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
+ + " stackInvisible=" + stackInvisible
+ + " behindFullscreenActivity=" + behindFullscreenActivity);
+ // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
+ // other tasks in the home stack could be visible if and only if:
+ // - some app is running in the docked stack;
+ // - no app is running in either the fullscreen stack or the freefrom stack.
+ final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
+ final ActivityStack fullscreenStack = mStackSupervisor.getStack(
+ FULLSCREEN_WORKSPACE_STACK_ID);
+ final ActivityStack freeformStack = mStackSupervisor.getStack(
+ FREEFORM_WORKSPACE_STACK_ID);
+ final boolean dockedStackEmpty = dockedStack == null ||
+ dockedStack.topRunningActivityLocked() == null;
+ final boolean fullscreenStackEmpty = fullscreenStack == null ||
+ fullscreenStack.topRunningActivityLocked() == null;
+ final boolean freeformStackEmpty = freeformStack == null ||
+ freeformStack.topRunningActivityLocked() == null;
+ behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
+ !freeformStackEmpty;
+ } else if (task.isHomeTask()) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
+ " stackInvisible=" + stackInvisible
+ " behindFullscreenActivity=" + behindFullscreenActivity);