Merge "Move Configuration creation from Window Manager to Activity Manager."
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index f86adfe..33c51ff 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -97,21 +97,21 @@
* @param launchTaskBehind True if the token is been launched from behind.
* @param taskBounds Bounds to use when creating a new Task with the input task Id if
* the task doesn't exist yet.
- * @return The configuration of the task if it was newly created. null otherwise.
+ * @param configuration Configuration that is being used with this task.
*/
- Configuration addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
+ void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
- in Rect taskBounds);
+ in Rect taskBounds, in Configuration configuration);
/**
*
* @param token The token we are adding to the input task Id.
* @param taskId The Id of the task we are adding the token to.
* @param taskBounds Bounds to use when creating a new Task with the input task Id if
* the task doesn't exist yet.
- * @return The configuration of the task if it was newly created. null otherwise.
+ * @param config Configuration that is being used with this task.
*/
- Configuration setAppTask(IBinder token, int taskId, in Rect taskBounds);
+ void setAppTask(IBinder token, int taskId, in Rect taskBounds, in Configuration config);
void setAppOrientation(IApplicationToken token, int requestedOrientation);
int getAppOrientation(IApplicationToken token);
void setFocusedApp(IBinder token, boolean moveFocusNow);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index f50df3a..37ddd4d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3975,8 +3975,7 @@
* for whatever reason. Ensures the HistoryRecord is updated with the
* correct configuration and all other bookkeeping is handled.
*/
- final boolean ensureActivityConfigurationLocked(ActivityRecord r,
- int globalChanges) {
+ final boolean ensureActivityConfigurationLocked(ActivityRecord r, int globalChanges) {
if (mConfigWillChange) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Skipping config check (will change): " + r);
@@ -4589,25 +4588,19 @@
void addConfigOverride(ActivityRecord r, TaskRecord task) {
final Rect bounds = task.getLaunchBounds();
- final Configuration config =
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
- r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind,
- bounds);
- if (config != null) {
- task.updateOverrideConfiguration(config, bounds);
- }
+ final Configuration config = task.updateOverrideConfiguration(mStackId, bounds);
+ mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
+ r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
+ (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
+ r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind,
+ bounds, config);
r.taskConfigOverride = task.mOverrideConfig;
}
private void setAppTask(ActivityRecord r, TaskRecord task) {
final Rect bounds = task.getLaunchBounds();
- final Configuration config =
- mWindowManager.setAppTask(r.appToken, task.taskId, task.getLaunchBounds());
- if (config != null) {
- task.updateOverrideConfiguration(config, bounds);
- }
+ final Configuration config = task.updateOverrideConfiguration(mStackId, bounds);
+ mWindowManager.setAppTask(r.appToken, task.taskId, task.getLaunchBounds(), config);
r.taskConfigOverride = task.mOverrideConfig;
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c86056b..33e0ef8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -97,7 +97,6 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
-import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -334,6 +333,9 @@
// temp. rect used during resize calculation so we don't need to create a new object each time.
private final Rect tempRect = new Rect();
+ private final SparseArray<Configuration> mTmpConfigs = new SparseArray<>();
+ private final SparseArray<Rect> mTmpBounds = new SparseArray<>();
+
/**
* Description of a request to start a new activity, which has been held
* due to app switches being disabled.
@@ -2917,19 +2919,19 @@
ActivityRecord r = stack.topRunningActivityLocked(null);
final boolean resizeTasks = r != null && r.task.mResizeable;
- final IntArray changedTaskIds = new IntArray(stack.numTasks());
- final List<Configuration> newTaskConfigs = new ArrayList<>(stack.numTasks());
- stack.mFullscreen = mWindowManager.resizeStack(
- stackId, bounds, resizeTasks, changedTaskIds, newTaskConfigs);
- for (int i = changedTaskIds.size() - 1; i >= 0; i--) {
- final TaskRecord task = anyTaskForIdLocked(changedTaskIds.get(i), false);
- if (task == null) {
- Slog.wtf(TAG, "Task in WindowManager, but not in ActivityManager???");
- continue;
+ mTmpBounds.clear();
+ mTmpConfigs.clear();
+ if (resizeTasks) {
+ ArrayList<TaskRecord> tasks = stack.getAllTasks();
+ for (int i = tasks.size() - 1; i >= 0; i--) {
+ TaskRecord task = tasks.get(i);
+ task.updateOverrideConfiguration(stackId, bounds);
+ mTmpConfigs.put(task.taskId, task.mOverrideConfig);
+ mTmpBounds.put(task.taskId, task.mBounds);
}
- task.updateOverrideConfiguration(newTaskConfigs.get(i), bounds);
}
-
+ stack.mFullscreen = mWindowManager.resizeStack(stackId, bounds, resizeTasks, mTmpConfigs,
+ mTmpBounds);
if (stack.mStackId == DOCKED_STACK_ID) {
// Dock stack funness...Yay!
if (stack.mFullscreen) {
@@ -3024,25 +3026,27 @@
stackId = FREEFORM_WORKSPACE_STACK_ID;
}
if (stackId != task.stack.mStackId) {
- final String reason = "resizeTask";
- final ActivityStack stack =
- moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, !FORCE_FOCUS, reason);
+ moveTaskToStackUncheckedLocked(task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
}
- final Configuration overrideConfig = mWindowManager.resizeTask(task.taskId, bounds);
- if (task.updateOverrideConfiguration(overrideConfig, bounds)) {
+ final Configuration overrideConfig = task.updateOverrideConfiguration(stackId, bounds);
+ // This variable holds information whether the configuration didn't change in a signficant
+ // way and the activity was kept the way it was. If it's false, it means the activity had
+ // to be relaunched due to configuration change.
+ boolean kept = true;
+ if (overrideConfig != null) {
ActivityRecord r = task.topRunningActivityLocked(null);
if (r != null) {
final ActivityStack stack = task.stack;
- final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
- // And we need to make sure at this point that all other activities
- // are made visible with the correct configuration.
+ kept = stack.ensureActivityConfigurationLocked(r, 0);
+ // All other activities must be made visible with their correct configuration.
ensureActivitiesVisibleLocked(r, 0);
- if (!updated) {
+ if (!kept) {
resumeTopActivitiesLocked(stack, null, null);
}
}
}
+ mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig, kept);
}
ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) {
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
index 5c4fd13..735c06f 100644
--- a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -234,7 +235,7 @@
break;
}
}
- task.setInitialBounds(proposal);
+ task.updateOverrideConfiguration(FREEFORM_WORKSPACE_STACK_ID, proposal);
}
private boolean shiftedToFar(Rect start, int shiftPolicy) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 9cbaec5..12c7b86 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -20,6 +20,7 @@
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;
+import static android.app.ActivityManager.INVALID_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
@@ -52,6 +53,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
+import android.util.DisplayMetrics;
import android.util.Slog;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.util.XmlUtils;
@@ -63,6 +65,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Objects;
final class TaskRecord {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
@@ -106,6 +109,13 @@
static final int INVALID_TASK_ID = -1;
+ // 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 int taskId; // Unique identifier for this task.
String affinity; // The affinity name for this task, or null; may change identity.
String rootAffinity; // Initial base affinity, or null; does not change from initial root.
@@ -218,6 +228,8 @@
Configuration mOverrideConfig = Configuration.EMPTY;
+ private Rect mTmpRect = new Rect();
+
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
mService = service;
@@ -271,8 +283,7 @@
long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
- int callingUid, String callingPackage, boolean resizeable, boolean privileged,
- Rect bounds) {
+ int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -309,7 +320,6 @@
mCallingPackage = callingPackage;
mResizeable = resizeable;
mPrivileged = privileged;
- mBounds = mLastNonFullscreenBounds = bounds;
}
void touchActiveTime() {
@@ -1163,7 +1173,8 @@
autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
- callingUid, callingPackage, resizeable, privileged, bounds);
+ callingUid, callingPackage, resizeable, privileged);
+ task.updateOverrideConfiguration(INVALID_STACK_ID, bounds);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
activities.get(activityNdx).task = task;
@@ -1173,25 +1184,51 @@
return task;
}
- boolean updateOverrideConfiguration(Configuration newConfig, Rect bounds) {
+ /**
+ * Update task's override configuration based on the bounds.
+ * @return Update configuration or null if there is no change.
+ */
+ Configuration updateOverrideConfiguration(int stackId, Rect bounds) {
+ if (stackId == 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.
+ bounds = fitWithinBounds(bounds);
+ }
+ if (Objects.equals(mBounds, bounds)) {
+ return null;
+ }
Configuration oldConfig = mOverrideConfig;
- mOverrideConfig = (newConfig == null) ? Configuration.EMPTY : newConfig;
- // We override the configuration only when the task's dimensions are different from the
- // display. In this manner, we know that if the override configuration is empty, the task
- // is necessarily fullscreen.
- mFullscreen = Configuration.EMPTY.equals(mOverrideConfig);
+
+ mFullscreen = bounds == null;
if (mFullscreen) {
if (mBounds != null && stack.mStackId != DOCKED_STACK_ID) {
mLastNonFullscreenBounds = mBounds;
}
mBounds = null;
+ mOverrideConfig = Configuration.EMPTY;
} else {
mBounds = new Rect(bounds);
if (stack.mStackId != DOCKED_STACK_ID) {
mLastNonFullscreenBounds = mBounds;
}
+
+ final Configuration serviceConfig = mService.mConfiguration;
+ mOverrideConfig = new Configuration(serviceConfig);
+ // TODO(multidisplay): Update Dp to that of display stack is on.
+ final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ mOverrideConfig.screenWidthDp =
+ Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
+ mOverrideConfig.screenHeightDp =
+ Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
+ mOverrideConfig.smallestScreenWidthDp =
+ Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
+ mOverrideConfig.orientation =
+ (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
+ ? Configuration.ORIENTATION_PORTRAIT
+ : Configuration.ORIENTATION_LANDSCAPE;
}
- return !mOverrideConfig.equals(oldConfig);
+ return !mOverrideConfig.equals(oldConfig) ? mOverrideConfig : null;
}
/** Returns the stack that should be used to launch this task. */
@@ -1225,12 +1262,39 @@
return mLastNonFullscreenBounds;
}
- void setInitialBounds(Rect rect) {
- if (mBounds == null) {
- mBounds = new Rect();
+ /** Fits the tasks within the input bounds adjusting the task bounds as needed.
+ * @param bounds Bounds to fit the task within. Nothing is done if null.
+ * @return Returns final configuration after updating with the adjusted bounds.
+ * */
+ Rect fitWithinBounds(Rect bounds) {
+ if (bounds == null || mBounds == null || bounds.contains(mBounds)) {
+ return bounds;
}
- mBounds.set(rect);
- mLastNonFullscreenBounds = mBounds;
+ mTmpRect.set(mBounds);
+
+ if (mBounds.left < bounds.left || mBounds.right > bounds.right) {
+ final int maxRight = bounds.right - (bounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
+ int horizontalDiff = bounds.left - mBounds.left;
+ if ((horizontalDiff < 0 && mBounds.left >= maxRight)
+ || (mBounds.left + horizontalDiff >= maxRight)) {
+ horizontalDiff = maxRight - mBounds.left;
+ }
+ mTmpRect.left += horizontalDiff;
+ mTmpRect.right += horizontalDiff;
+ }
+
+ if (mBounds.top < bounds.top || mBounds.bottom > bounds.bottom) {
+ final int maxBottom = bounds.bottom - (bounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
+ int verticalDiff = bounds.top - mBounds.top;
+ if ((verticalDiff < 0 && mBounds.top >= maxBottom)
+ || (mBounds.top + verticalDiff >= maxBottom)) {
+ verticalDiff = maxBottom - mBounds.top;
+ }
+ mTmpRect.top += verticalDiff;
+ mTmpRect.bottom += verticalDiff;
+ }
+
+ return mTmpRect;
}
void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 554af28..666d902 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -23,7 +23,6 @@
import android.content.res.Configuration;
import android.graphics.Rect;
-import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
@@ -41,13 +40,6 @@
* when no window animation is driving it. */
private static final int DEFAULT_DIM_DURATION = 200;
- // The amount we divide the height/width of the bounds we are trying to fit the task within
- // when using the 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;
-
TaskStack mStack;
final AppTokenList mAppTokens = new AppTokenList();
final int mTaskId;
@@ -84,13 +76,13 @@
// of creating a new object per fullscreen task on a display.
private static final SparseArray<DimLayer> sSharedFullscreenDimLayers = new SparseArray<>();
- Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds) {
+ Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
+ Configuration config) {
mTaskId = taskId;
mStack = stack;
mUserId = userId;
mService = service;
- mOverrideConfig = Configuration.EMPTY;
- setBounds(bounds);
+ setBounds(bounds, config);
}
DisplayContent getDisplayContent() {
@@ -172,43 +164,18 @@
}
}
- /** Fits the tasks within the input bounds adjusting the task bounds as needed.
- * @param bounds Bounds to fit the task within. Nothing is done if null.
- * @return Returns true if the task bounds was adjusted in any way.
- * */
- boolean fitWithinBounds(Rect bounds) {
- if (bounds == null || bounds.contains(mBounds)) {
- return false;
- }
- mTmpRect2.set(mBounds);
-
- if (mBounds.left < bounds.left || mBounds.right > bounds.right) {
- final int maxRight = bounds.right - (bounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
- int horizontalDiff = bounds.left - mBounds.left;
- if ((horizontalDiff < 0 && mBounds.left >= maxRight)
- || (mBounds.left + horizontalDiff >= maxRight)) {
- horizontalDiff = maxRight - mBounds.left;
- }
- mTmpRect2.left += horizontalDiff;
- mTmpRect2.right += horizontalDiff;
- }
-
- if (mBounds.top < bounds.top || mBounds.bottom > bounds.bottom) {
- final int maxBottom = bounds.bottom - (bounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
- int verticalDiff = bounds.top - mBounds.top;
- if ((verticalDiff < 0 && mBounds.top >= maxBottom)
- || (mBounds.top + verticalDiff >= maxBottom)) {
- verticalDiff = maxBottom - mBounds.top;
- }
- mTmpRect2.top += verticalDiff;
- mTmpRect2.bottom += verticalDiff;
- }
-
- return setBounds(mTmpRect2);
- }
-
/** Set the task bounds. Passing in null sets the bounds to fullscreen. */
- boolean setBounds(Rect bounds) {
+ boolean setBounds(Rect bounds, Configuration config) {
+ if (config == null) {
+ config = Configuration.EMPTY;
+ }
+ if (bounds == null && !Configuration.EMPTY.equals(config)) {
+ throw new IllegalArgumentException("null bounds but non empty configuration: "
+ + config);
+ }
+ if (bounds != null && Configuration.EMPTY.equals(config)) {
+ throw new IllegalArgumentException("non null bounds, but empty configuration");
+ }
boolean oldFullscreen = mFullscreen;
int rotation = Surface.ROTATION_0;
final DisplayContent displayContent = mStack.getDisplayContent();
@@ -241,7 +208,7 @@
mBounds.set(bounds);
mRotation = rotation;
updateDimLayer();
- updateOverrideConfiguration();
+ mOverrideConfig = mFullscreen ? Configuration.EMPTY : config;
return true;
}
@@ -249,36 +216,12 @@
out.set(mBounds);
}
- private void updateOverrideConfiguration() {
- final Configuration serviceConfig = mService.mCurConfiguration;
- if (mFullscreen) {
- mOverrideConfig = Configuration.EMPTY;
- return;
- }
-
- if (mOverrideConfig == Configuration.EMPTY) {
- mOverrideConfig = new Configuration();
- }
-
- // TODO(multidisplay): Update Dp to that of display stack is on.
- final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
- mOverrideConfig.screenWidthDp =
- Math.min((int)(mBounds.width() / density), serviceConfig.screenWidthDp);
- mOverrideConfig.screenHeightDp =
- Math.min((int)(mBounds.height() / density), serviceConfig.screenHeightDp);
- mOverrideConfig.smallestScreenWidthDp =
- Math.min(mOverrideConfig.screenWidthDp, mOverrideConfig.screenHeightDp);
- mOverrideConfig.orientation =
- (mOverrideConfig.screenWidthDp <= mOverrideConfig.screenHeightDp)
- ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
- }
-
void updateDisplayInfo(final DisplayContent displayContent) {
if (displayContent == null) {
return;
}
if (mFullscreen) {
- setBounds(null);
+ setBounds(null, Configuration.EMPTY);
return;
}
final int newRotation = displayContent.getDisplayInfo().rotation;
@@ -313,7 +256,7 @@
mTmpRect2.bottom = mTmpRect2.top + mBounds.width();
break;
}
- setBounds(mTmpRect2);
+ setBounds(mTmpRect2, mOverrideConfig);
}
/** Updates the dim layer bounds, recreating it if needed. */
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 25a71d9..a7ef2f8 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -27,6 +27,7 @@
import android.util.EventLog;
import android.util.IntArray;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.DisplayInfo;
import com.android.server.EventLogTags;
@@ -96,15 +97,15 @@
/**
* Set the bounds of the stack and its containing tasks.
- * @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
+ * @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
* @param resizeTasks If true, the tasks within the stack will also be resized.
- * @param changedTaskIds Output list of Ids of tasks that changed in bounds.
- * @param newTaskConfigs Output list of new Configuation of the tasks that changed.
+ * @param configs Configuration for individual tasks, keyed by task id.
+ * @param taskBounds Bounds for individual tasks, keyed by task id.
* @return True if the stack bounds was changed.
* */
- boolean setBounds(Rect bounds, boolean resizeTasks, IntArray changedTaskIds,
- List<Configuration> newTaskConfigs) {
- if (!setBounds(bounds)) {
+ boolean setBounds(Rect stackBounds, boolean resizeTasks, SparseArray<Configuration> configs,
+ SparseArray<Rect> taskBounds) {
+ if (!setBounds(stackBounds)) {
return false;
}
@@ -113,20 +114,17 @@
}
// Update bounds of containing tasks.
- final Rect newBounds = mFullscreen ? null : mBounds;
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
final Task task = mTasks.get(taskNdx);
- 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.
- if (task.fitWithinBounds(newBounds)) {
- changedTaskIds.add(task.mTaskId);
- newTaskConfigs.add(task.mOverrideConfig);
+ Configuration config = configs.get(task.mTaskId);
+ if (config != null) {
+ Rect bounds = taskBounds.get(task.mTaskId);
+ if (bounds == null) {
+ bounds = stackBounds;
}
- } else if (task.setBounds(newBounds)) {
- changedTaskIds.add(task.mTaskId);
- newTaskConfigs.add(task.mOverrideConfig);
+ task.setBounds(bounds, config);
+ } else {
+ Slog.wtf(TAG, "No config for task: " + task + ", is there a mismatch with AM?");
}
}
return true;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index cf690a5..bf7d1e7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3041,8 +3041,8 @@
Binder.restoreCallingIdentity(origId);
}
- private Task createTaskLocked(
- int taskId, int stackId, int userId, AppWindowToken atoken, Rect bounds) {
+ private Task createTaskLocked(int taskId, int stackId, int userId, AppWindowToken atoken,
+ Rect bounds, Configuration config) {
if (DEBUG_STACK) Slog.i(TAG, "createTaskLocked: taskId=" + taskId + " stackId=" + stackId
+ " atoken=" + atoken + " bounds=" + bounds);
final TaskStack stack = mStackIdToStack.get(stackId);
@@ -3050,17 +3050,17 @@
throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
}
EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
- Task task = new Task(taskId, stack, userId, this, bounds);
+ Task task = new Task(taskId, stack, userId, this, bounds, config);
mTaskIdToTask.put(taskId, task);
stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */, atoken.showForAllUsers);
return task;
}
@Override
- public Configuration addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
+ public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int userId,
int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
- Rect taskBounds) {
+ Rect taskBounds, Configuration config) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3084,7 +3084,7 @@
AppWindowToken atoken = findAppWindowToken(token.asBinder());
if (atoken != null) {
Slog.w(TAG, "Attempted to add existing app token: " + token);
- return null;
+ return;
}
atoken = new AppWindowToken(this, token, voiceInteraction);
atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
@@ -3098,10 +3098,8 @@
+ " to stack=" + stackId + " task=" + taskId + " at " + addPos);
Task task = mTaskIdToTask.get(taskId);
- Configuration outConfig = null;
if (task == null) {
- task = createTaskLocked(taskId, stackId, userId, atoken, taskBounds);
- outConfig = task.mOverrideConfig;
+ task = createTaskLocked(taskId, stackId, userId, atoken, taskBounds, config);
}
task.addAppToken(addPos, atoken);
@@ -3110,13 +3108,11 @@
// Application tokens start out hidden.
atoken.hidden = true;
atoken.hiddenRequested = true;
-
- return outConfig;
}
}
@Override
- public Configuration setAppTask(IBinder token, int taskId, Rect taskBounds) {
+ public void setAppTask(IBinder token, int taskId, Rect taskBounds, Configuration config) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppTask()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3126,20 +3122,18 @@
final AppWindowToken atoken = findAppWindowToken(token);
if (atoken == null) {
Slog.w(TAG, "Attempted to set task id of non-existing app token: " + token);
- return null;
+ return;
}
final Task oldTask = atoken.mTask;
oldTask.removeAppToken(atoken);
Task newTask = mTaskIdToTask.get(taskId);
- Configuration outConfig = null;
if (newTask == null) {
newTask = createTaskLocked(
- taskId, oldTask.mStack.mStackId, oldTask.mUserId, atoken, taskBounds);
- outConfig = newTask.mOverrideConfig;
+ taskId, oldTask.mStack.mStackId, oldTask.mUserId, atoken, taskBounds,
+ config);
}
newTask.addAppToken(Integer.MAX_VALUE /* at top */, atoken);
- return outConfig;
}
}
@@ -4599,19 +4593,19 @@
* @param stackId Id of stack to resize.
* @param bounds New stack bounds. Passing in null sets the bounds to fullscreen.
* @param resizeTasks If true, the tasks within the stack will also be resized.
- * @param changedTaskIds Output list of Ids of tasks that changed in bounds due to resize.
- * @param newTaskConfigs Output list of new Configuation of the tasks that changed.
+ * @param configs Configurations for tasks in the resized stack, keyed by task id.
+ * @param taskBounds Bounds for tasks in the resized stack, keyed by task id.
* @return True if the stack is now fullscreen.
* */
public boolean resizeStack(int stackId, Rect bounds, boolean resizeTasks,
- IntArray changedTaskIds, List<Configuration> newTaskConfigs) {
+ SparseArray<Configuration> configs, SparseArray<Rect> taskBounds) {
synchronized (mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
if (stack == null) {
throw new IllegalArgumentException("resizeStack: stackId " + stackId
+ " not found.");
}
- if (stack.setBounds(bounds, resizeTasks, changedTaskIds, newTaskConfigs)) {
+ if (stack.setBounds(bounds, resizeTasks, configs, taskBounds)) {
stack.resizeWindows();
stack.getDisplayContent().layoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
@@ -4648,19 +4642,20 @@
* Returns a {@link Configuration} object that contains configurations settings
* that should be overridden due to the operation.
*/
- public Configuration resizeTask(int taskId, Rect bounds) {
+ public void resizeTask(int taskId, Rect bounds, Configuration configuration, boolean relayout) {
synchronized (mWindowMap) {
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
throw new IllegalArgumentException("resizeTask: taskId " + taskId
+ " not found.");
}
- if (task.setBounds(bounds)) {
+ if (task.setBounds(bounds, configuration)) {
task.resizeWindows();
- task.getDisplayContent().layoutNeeded = true;
- performLayoutAndPlaceSurfacesLocked();
+ if (relayout) {
+ task.getDisplayContent().layoutNeeded = true;
+ performLayoutAndPlaceSurfacesLocked();
+ }
}
- return new Configuration(task.mOverrideConfig);
}
}
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 6177784..95f676e 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -32,7 +32,7 @@
*/
public class WindowManagerPermissionTests extends TestCase {
IWindowManager mWm;
-
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -51,7 +51,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.resumeKeyDispatching(null);
fail("IWindowManager.resumeKeyDispatching did not throw SecurityException as"
@@ -61,7 +61,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setEventDispatching(true);
fail("IWindowManager.setEventDispatching did not throw SecurityException as"
@@ -71,7 +71,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.addWindowToken(null, 0);
fail("IWindowManager.addWindowToken did not throw SecurityException as"
@@ -81,7 +81,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.removeWindowToken(null);
fail("IWindowManager.removeWindowToken did not throw SecurityException as"
@@ -91,9 +91,10 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
- mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false, null);
+ mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false, null,
+ Configuration.EMPTY);
fail("IWindowManager.addAppToken did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -101,9 +102,9 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
- mWm.setAppTask(null, 0, null);
+ mWm.setAppTask(null, 0, null, null);
fail("IWindowManager.setAppGroupId did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -111,7 +112,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.updateOrientationFromAppTokens(new Configuration(), null);
fail("IWindowManager.updateOrientationFromAppTokens did not throw SecurityException as"
@@ -121,7 +122,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setAppOrientation(null, 0);
mWm.addWindowToken(null, 0);
@@ -132,7 +133,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setFocusedApp(null, false);
fail("IWindowManager.setFocusedApp did not throw SecurityException as"
@@ -142,7 +143,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.prepareAppTransition(0, false);
fail("IWindowManager.prepareAppTransition did not throw SecurityException as"
@@ -152,7 +153,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.executeAppTransition();
fail("IWindowManager.executeAppTransition did not throw SecurityException as"
@@ -162,7 +163,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, 0, null, false);
fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
@@ -172,7 +173,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setAppWillBeHidden(null);
fail("IWindowManager.setAppWillBeHidden did not throw SecurityException as"
@@ -182,7 +183,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setAppVisibility(null, false);
fail("IWindowManager.setAppVisibility did not throw SecurityException as"
@@ -192,7 +193,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.startAppFreezingScreen(null, 0);
fail("IWindowManager.startAppFreezingScreen did not throw SecurityException as"
@@ -202,7 +203,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.stopAppFreezingScreen(null, false);
fail("IWindowManager.stopAppFreezingScreen did not throw SecurityException as"
@@ -212,7 +213,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.removeAppToken(null);
fail("IWindowManager.removeAppToken did not throw SecurityException as"
@@ -236,7 +237,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.reenableKeyguard(token);
fail("IWindowManager.reenableKeyguard did not throw SecurityException as"
@@ -246,7 +247,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.exitKeyguardSecurely(null);
fail("IWindowManager.exitKeyguardSecurely did not throw SecurityException as"
@@ -257,7 +258,7 @@
fail("Unexpected remote exception");
}
}
-
+
@SmallTest
public void testSET_ANIMATION_SCALE() {
try {
@@ -269,7 +270,7 @@
} catch (RemoteException e) {
fail("Unexpected remote exception");
}
-
+
try {
mWm.setAnimationScales(new float[1]);
fail("IWindowManager.setAnimationScales did not throw SecurityException as"
@@ -280,7 +281,7 @@
fail("Unexpected remote exception");
}
}
-
+
@SmallTest
public void testSET_ORIENTATION() {
try {