Move updating stack override config to ActivityStack
Also added some multi-display TODOs.
Change-Id: Iada3f84c4f57c9623fc7f116819d4e0267ebc32a
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8782820..51eef89 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1715,6 +1715,7 @@
}
if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
ar.packageName)) {
+ // TODO(multi-display): Show dialog on appropriate display.
mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
ActivityManagerService.this, mContext, ar.info.applicationInfo);
mUnsupportedDisplaySizeDialog.show();
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 806416d..b82e28d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -118,6 +118,7 @@
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.Display;
import com.android.internal.app.IVoiceInteractor;
@@ -228,6 +229,13 @@
// stack and the new stack will be on top of all stacks.
static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
+ // The height/width divide used when fitting a task within a bounds with method
+ // {@link #fitWithinBounds}.
+ // We always want the task to to be visible in the bounds without affecting its size when
+ // fitting. To make sure this is the case, we don't adjust the task left or top side pass
+ // the input bounds right or bottom side minus the width or height divided by this value.
+ private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
+
final ActivityManagerService mService;
final WindowManagerService mWindowManager;
private final RecentTasks mRecentTasks;
@@ -321,6 +329,12 @@
/** The attached Display's unique identifier, or -1 if detached */
int mDisplayId;
+ /** Temp variables used during override configuration update. */
+ private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
+ private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
+ private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>();
+ private final Rect tempRect2 = new Rect();
+
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
@@ -4524,6 +4538,86 @@
}
}
+ /** Update override configurations of all tasks in the stack. */
+ void updateOverrideConfiguration(Rect stackBounds, Rect tempTaskBounds,
+ Rect tempTaskInsetBounds) {
+
+ final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : stackBounds;
+ final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
+
+ mTmpBounds.clear();
+ mTmpConfigs.clear();
+ mTmpInsetBounds.clear();
+
+ for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
+ final TaskRecord task = mTaskHistory.get(i);
+ if (task.isResizeable()) {
+ if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+ // For freeform stack we don't adjust the size of the tasks to match that
+ // of the stack, but we do try to make sure the tasks are still contained
+ // with the bounds of the stack.
+ tempRect2.set(task.mBounds);
+ fitWithinBounds(tempRect2, stackBounds);
+ task.updateOverrideConfiguration(tempRect2);
+ } else {
+ task.updateOverrideConfiguration(taskBounds, insetBounds);
+ }
+ }
+
+ mTmpConfigs.put(task.taskId, task.mOverrideConfig);
+ mTmpBounds.put(task.taskId, task.mBounds);
+ if (tempTaskInsetBounds != null) {
+ mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
+ }
+ }
+
+ // We might trigger a configuration change. Save the current task bounds for freezing.
+ mWindowManager.prepareFreezingTaskBounds(mStackId);
+ mFullscreen = mWindowManager.resizeStack(mStackId, stackBounds, mTmpConfigs, mTmpBounds,
+ mTmpInsetBounds);
+ setBounds(stackBounds);
+ }
+
+
+ /**
+ * Adjust bounds to stay within stack bounds.
+ *
+ * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
+ * that keep them unchanged, but be contained within the stack bounds.
+ *
+ * @param bounds Bounds to be adjusted.
+ * @param stackBounds Bounds within which the other bounds should remain.
+ */
+ private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
+ if (stackBounds == null || stackBounds.contains(bounds)) {
+ return;
+ }
+
+ if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
+ final int maxRight = stackBounds.right
+ - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
+ int horizontalDiff = stackBounds.left - bounds.left;
+ if ((horizontalDiff < 0 && bounds.left >= maxRight)
+ || (bounds.left + horizontalDiff >= maxRight)) {
+ horizontalDiff = maxRight - bounds.left;
+ }
+ bounds.left += horizontalDiff;
+ bounds.right += horizontalDiff;
+ }
+
+ if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
+ final int maxBottom = stackBounds.bottom
+ - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
+ int verticalDiff = stackBounds.top - bounds.top;
+ if ((verticalDiff < 0 && bounds.top >= maxBottom)
+ || (bounds.top + verticalDiff >= maxBottom)) {
+ verticalDiff = maxBottom - bounds.top;
+ }
+ bounds.top += verticalDiff;
+ bounds.bottom += verticalDiff;
+ }
+ }
+
/**
* Make sure the given activity matches the current configuration. Returns false if the activity
* had to be destroyed. Returns true if the configuration is the same, or the activity will
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 80d51e5..8602bb6 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -267,13 +267,6 @@
/** Action restriction: launching the activity is restricted by an app op. */
private static final int ACTIVITY_RESTRICTION_APPOP = 2;
- // The height/width divide used when fitting a task within a bounds with method
- // {@link #fitWithinBounds}.
- // We always want the task to to be visible in the bounds without affecting its size when
- // fitting. To make sure this is the case, we don't adjust the task left or top side pass
- // the input bounds right or bottom side minus the width or height divided by this value.
- private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
-
/** Status Bar Service **/
private IBinder mToken = new Binder();
private IStatusBarService mStatusBarService;
@@ -402,13 +395,11 @@
/** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */
boolean inResumeTopActivity;
- // temp. rects used during resize calculation so we don't need to create a new object each time.
+ /**
+ * Temporary rect used during docked stack resize calculation so we don't need to create a new
+ * object each time.
+ */
private final Rect tempRect = new Rect();
- private final Rect tempRect2 = new Rect();
-
- private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
- private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
- private final SparseArray<Rect> mTmpInsetBounds = new SparseArray<>();
// The default minimal size that will be used if the activity doesn't specify its minimal size.
// It will be calculated when the default display gets added.
@@ -1912,6 +1903,7 @@
if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
return null;
}
+ // TODO(multi-display): Allow creating stacks on secondary displays.
return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
}
@@ -1923,14 +1915,6 @@
return allStacks;
}
- IBinder getHomeActivityToken() {
- ActivityRecord homeActivity = getHomeActivity();
- if (homeActivity != null) {
- return homeActivity.appToken;
- }
- return null;
- }
-
ActivityRecord getHomeActivity() {
return getHomeActivityForUser(mCurrentUser);
}
@@ -2060,39 +2044,7 @@
return;
}
- mTmpBounds.clear();
- mTmpConfigs.clear();
- mTmpInsetBounds.clear();
- final ArrayList<TaskRecord> tasks = stack.getAllTasks();
- final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
- final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds;
- for (int i = tasks.size() - 1; i >= 0; i--) {
- final TaskRecord task = tasks.get(i);
- if (task.isResizeable()) {
- if (stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
- // For freeform stack we don't adjust the size of the tasks to match that
- // of the stack, but we do try to make sure the tasks are still contained
- // with the bounds of the stack.
- tempRect2.set(task.mBounds);
- fitWithinBounds(tempRect2, bounds);
- task.updateOverrideConfiguration(tempRect2);
- } else {
- task.updateOverrideConfiguration(taskBounds, insetBounds);
- }
- }
-
- mTmpConfigs.put(task.taskId, task.mOverrideConfig);
- mTmpBounds.put(task.taskId, task.mBounds);
- if (tempTaskInsetBounds != null) {
- mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
- }
- }
-
- // We might trigger a configuration change. Save the current task bounds for freezing.
- mWindowManager.prepareFreezingTaskBounds(stack.mStackId);
- stack.mFullscreen = mWindowManager.resizeStack(stack.mStackId, bounds, mTmpConfigs,
- mTmpBounds, mTmpInsetBounds);
- stack.setBounds(bounds);
+ stack.updateOverrideConfiguration(bounds, tempTaskBounds, tempTaskInsetBounds);
}
void moveTasksToFullscreenStackLocked(int fromStackId, boolean onTop) {
@@ -4371,45 +4323,6 @@
}
}
- /**
- * Adjust bounds to stay within stack bounds.
- *
- * Since bounds might be outside of stack bounds, this method tries to move the bounds in a way
- * that keep them unchanged, but be contained within the stack bounds.
- *
- * @param bounds Bounds to be adjusted.
- * @param stackBounds Bounds within which the other bounds should remain.
- */
- private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
- if (stackBounds == null || stackBounds.contains(bounds)) {
- return;
- }
-
- if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
- final int maxRight = stackBounds.right
- - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
- int horizontalDiff = stackBounds.left - bounds.left;
- if ((horizontalDiff < 0 && bounds.left >= maxRight)
- || (bounds.left + horizontalDiff >= maxRight)) {
- horizontalDiff = maxRight - bounds.left;
- }
- bounds.left += horizontalDiff;
- bounds.right += horizontalDiff;
- }
-
- if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
- final int maxBottom = stackBounds.bottom
- - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
- int verticalDiff = stackBounds.top - bounds.top;
- if ((verticalDiff < 0 && bounds.top >= maxBottom)
- || (bounds.top + verticalDiff >= maxBottom)) {
- verticalDiff = maxBottom - bounds.top;
- }
- bounds.top += verticalDiff;
- bounds.bottom += verticalDiff;
- }
- }
-
ActivityStack findStackBehind(ActivityStack stack) {
// TODO(multi-display): We are only looking for stacks on the default display.
final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
@@ -4525,6 +4438,8 @@
* entry will be the focused activity.
*/
public List<IBinder> getTopVisibleActivities() {
+ // TODO(multi-display): Get rid of DEFAULT_DISPLAY here. Used in
+ // VoiceInteractionManagerServiceImpl#showSessionLocked.
final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
if (display == null) {
return Collections.EMPTY_LIST;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 475b155..2b00f86 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -220,6 +220,7 @@
void applyDisplaySize(WindowManagerService wm) {
if (!mHaveDisplaySize) {
Point p = new Point();
+ // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
if (p.x != 0 && p.y != 0) {
updateOomLevels(p.x, p.y, true);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2828b96..f9aa66b 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -325,6 +325,8 @@
// The token is not closing nor opening, so even if there is an animation set, that
// doesn't mean that it goes through the normal app transition cycle so we have
// to inform the docked controller about visibility change.
+ // TODO(multi-display): notify docked divider on all displays where visibility was
+ // affected.
mService.getDefaultDisplayContentLocked().getDockedDividerController()
.notifyAppVisibilityChanged();
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0501fdc..7a32845 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8804,6 +8804,7 @@
if (line != null) {
String[] toks = line.split("%");
if (toks != null && toks.length > 0) {
+ // TODO(multi-display): Show watermarks on secondary displays.
mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
mRealDisplayMetrics, mFxSession, toks);
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 5025df6..8f2723c 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -303,6 +303,7 @@
mSustainedPerformanceModeCurrent = false;
mService.mTransactionSequence++;
+ // TODO(multi-display): Perform same actions on all displays.
final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
final int defaultDw = defaultInfo.logicalWidth;