Added support for docked stack
Docked stacks occupy a dedicated region on a display.
When a docked stack is present all other static stacks bounds
are restricted to the region of the screen not occupied by
the docked stack.
Change-Id: I6aec3aa19c41a7e756375002f3a925977b5533b5
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 18a0a36..356565f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityManager.DOCKED_STACK_ID;
import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.HOME_STACK_ID;
@@ -229,6 +230,8 @@
// Whether or not this stack covers the entire screen; by default stacks are fullscreen
boolean mFullscreen = true;
+ // Current bounds of the stack or null if fullscreen.
+ Rect mBounds = null;
long mLaunchStartTime = 0;
long mFullyDrawnStartTime = 0;
@@ -1227,8 +1230,42 @@
return null;
}
- // Checks if any of the stacks above this one has a fullscreen activity behind it.
- // If so, this stack is hidden, otherwise it is visible.
+ /** Returns true if the stack contains a fullscreen task. */
+ private boolean hasFullscreenTask() {
+ for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
+ final TaskRecord task = mTaskHistory.get(i);
+ if (task.mFullscreen) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Return true if this stack is hidden by the presence of a docked stack. */
+ private boolean isHiddenByDockedStack() {
+ final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
+ if (dockedStack != null) {
+ final int dockedStackIndex = mStacks.indexOf(dockedStack);
+ final int stackIndex = mStacks.indexOf(this);
+ if (dockedStackIndex > stackIndex) {
+ // Fullscreen stacks or stacks with fullscreen task below the docked stack are not
+ // visible. We do this so we don't have the 2 stacks and their tasks overlap.
+ if (mFullscreen) {
+ return true;
+ }
+
+ // We need to also check the tasks in the stack because they can be fullscreen
+ // even though their stack isn't due to their root activity not been resizeable
+ // (i.e. doesn't support multi-window mode).
+ if (hasFullscreenTask()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /** Returns true if the stack is considered visible. */
private boolean isStackVisibleLocked() {
if (!isAttached()) {
return false;
@@ -1238,12 +1275,15 @@
return true;
}
- // Any stack that isn't the front stack is not visible, except for the case of the home
- // stack behind the main application stack since we can have dialog activities on the
- // main application stack that need the home stack to display behind them.
- // TODO(multi-window): Also need to add exception for side-by-side stacks.
- final boolean homeStack = mStackId == HOME_STACK_ID;
- if (!homeStack) {
+ final int stackIndex = mStacks.indexOf(this);
+
+ if (stackIndex == mStacks.size() - 1) {
+ Slog.wtf(TAG,
+ "Stack=" + this + " isn't front stack but is at the top of the stack list");
+ return false;
+ }
+
+ if (isHiddenByDockedStack()) {
return false;
}
@@ -1252,13 +1292,24 @@
* fullscreen activity, or a translucent activity that requested the
* wallpaper to be shown behind it.
*/
- for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
+ for (int i = stackIndex + 1; i < mStacks.size(); i++) {
final ActivityStack stack = mStacks.get(i);
- if (stack.mStackId != FULLSCREEN_WORKSPACE_STACK_ID) {
+ final ArrayList<TaskRecord> tasks = stack.getAllTasks();
+
+ if (!stack.mFullscreen && !stack.hasFullscreenTask()) {
+ continue;
+ }
+
+ if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID
+ || stack.mStackId == HOME_STACK_ID) {
+ // The freeform and home stacks can't have any other stack visible behind them
+ // when they are fullscreen since they act as base/cut-off points for visibility.
+ // NOTE: we don't cut-off at the FULLSCREEN_WORKSPACE_STACK_ID because the home
+ // stack sometimes needs to be visible behind it when it is displaying a dialog
+ // activity. We let it fall through to the logic below to determine visibility.
return false;
}
- final ArrayList<TaskRecord> tasks = stack.getAllTasks();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = tasks.get(taskNdx);
// task above isn't fullscreen, so, we assume we're still visible.
@@ -2680,9 +2731,10 @@
ActivityRecord next = topRunningActivityLocked(null);
final String myReason = reason + " adjustFocus";
if (next != r) {
- if (next != null && mStackId == FREEFORM_WORKSPACE_STACK_ID) {
- // For freeform stack we always keep the focus within the stack as long as
- // there is a running activity in the stack that we can adjust focus to.
+ if (next != null && (mStackId == FREEFORM_WORKSPACE_STACK_ID
+ || mStackId == DOCKED_STACK_ID)) {
+ // For freeform and docked stacks we always keep the focus within the stack as
+ // long as there is a running activity in the stack that we can adjust focus to.
mService.setFocusedActivityLocked(next, myReason);
return;
} else {
@@ -4321,7 +4373,10 @@
printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
mTaskHistory.get(taskNdx).mActivities, " ", "Hist", true, !dumpAll,
dumpClient, dumpPackage, needSep, header,
- " Task id #" + task.taskId);
+ " Task id #" + task.taskId + "\n" +
+ " mFullscreen=" + task.mFullscreen + "\n" +
+ " mBounds=" + task.mBounds + "\n" +
+ " mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds);
if (printed) {
header = null;
}