diff options
18 files changed, 143 insertions, 107 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index d45bc5dc8789..ba93b2a2cafe 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -166,7 +166,7 @@ public class Am extends BaseCommand { " am stack info <STACK_ID>\n" + " am task lock <TASK_ID>\n" + " am task lock stop\n" + - " am task resizeable <TASK_ID> [true|false]\n" + + " am task resizeable <TASK_ID> [0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)]\n" + " am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" + " am task drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS] \n" + " am task size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS] \n" + @@ -323,7 +323,8 @@ public class Am extends BaseCommand { "\n" + "am task lock stop: end the current task lock.\n" + "\n" + - "am task resizeable: change if <TASK_ID> is resizeable (true) or not (false).\n" + + "am task resizeable: change resizeable mode of <TASK_ID>.\n" + + " 0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)\n" + "\n" + "am task resize: makes sure <TASK_ID> is in a stack with the specified bounds.\n" + " Forces the task to be resizeable and creates a stack if no existing stack\n" + @@ -1985,10 +1986,10 @@ public class Am extends BaseCommand { final String taskIdStr = nextArgRequired(); final int taskId = Integer.valueOf(taskIdStr); final String resizeableStr = nextArgRequired(); - final boolean resizeable = Boolean.valueOf(resizeableStr); + final int resizeableMode = Integer.valueOf(resizeableStr); try { - mAm.setTaskResizeable(taskId, resizeable); + mAm.setTaskResizeable(taskId, resizeableMode); } catch (RemoteException e) { } } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index cd5797ecb286..138ff6d08419 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -2587,9 +2587,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case SET_TASK_RESIZEABLE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - int taskId = data.readInt(); - boolean resizeable = (data.readInt() == 1) ? true : false; - setTaskResizeable(taskId, resizeable); + final int taskId = data.readInt(); + final int resizeableMode = data.readInt(); + setTaskResizeable(taskId, resizeableMode); reply.writeNoException(); return true; } @@ -6307,12 +6307,12 @@ class ActivityManagerProxy implements IActivityManager } @Override - public void setTaskResizeable(int taskId, boolean resizeable) throws RemoteException { + public void setTaskResizeable(int taskId, int resizeableMode) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(taskId); - data.writeInt(resizeable ? 1 : 0); + data.writeInt(resizeableMode); mRemote.transact(SET_TASK_RESIZEABLE_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 5b3ffe05451a..cefbb8079590 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -530,7 +530,7 @@ public interface IActivityManager extends IInterface { public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values) throws RemoteException; - public void setTaskResizeable(int taskId, boolean resizeable) throws RemoteException; + public void setTaskResizeable(int taskId, int resizeableMode) throws RemoteException; public void resizeTask(int taskId, Rect bounds, int resizeMode) throws RemoteException; public Rect getTaskBounds(int taskId) throws RemoteException; diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 91a8e0a96191..10b8a30a2fb1 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -785,7 +785,12 @@ public class ActivityInfo extends ComponentInfo } /** @hide */ - public static final String resizeModeToString(int mode) { + public static boolean isResizeableMode(int mode) { + return mode == RESIZE_MODE_RESIZEABLE || mode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE; + } + + /** @hide */ + public static String resizeModeToString(int mode) { switch (mode) { case RESIZE_MODE_UNRESIZEABLE: return "RESIZE_MODE_UNRESIZEABLE"; diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index b045c17a9295..27ea92d63c53 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -101,15 +101,16 @@ interface IWindowManager * @param taskBounds Bounds to use when creating a new Task with the input task Id if * the task doesn't exist yet. * @param configuration Configuration that is being used with this task. - * @param cropWindowsToStack True if the app windows should be cropped to the stack bounds. + * @param taskResizeMode The resize mode of the task. * @param alwaysFocusable True if the app windows are always focusable regardless of the stack * they are in. + * @param homeTask True if this is the task. */ 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 Configuration configuration, boolean cropWindowsToStack, - boolean alwaysFocusable); + in Rect taskBounds, in Configuration configuration, int taskResizeMode, + boolean alwaysFocusable, boolean homeTask); /** * * @param token The token we are adding to the input task Id. @@ -119,9 +120,11 @@ interface IWindowManager * @param taskBounds Bounds to use when creating a new Task with the input task Id if * the task doesn't exist yet. * @param config Configuration that is being used with this task. + * @param taskResizeMode The resize mode of the task. + * @param homeTask True if this is the task. */ - void setAppTask( - IBinder token, int taskId, int stackId, in Rect taskBounds, in Configuration config); + void setAppTask(IBinder token, int taskId, int stackId, in Rect taskBounds, + in Configuration config, int taskResizeMode, boolean homeTask); 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/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b5982c308c08..66758fcb4cd6 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8875,7 +8875,7 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void setTaskResizeable(int taskId, boolean resizeable) { + public void setTaskResizeable(int taskId, int resizeableMode) { synchronized (this) { final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); @@ -8883,9 +8883,9 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found"); return; } - if (task.mResizeable != resizeable) { - task.mResizeable = resizeable; - mWindowManager.setTaskResizeable(taskId, resizeable); + if (task.mResizeMode != resizeableMode) { + task.mResizeMode = resizeableMode; + mWindowManager.setTaskResizeable(taskId, resizeableMode); mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); mStackSupervisor.resumeFocusedStackTopActivityLocked(); } @@ -8904,10 +8904,10 @@ public final class ActivityManagerService extends ActivityManagerNative return; } int stackId = task.stack.mStackId; - // First, check if this is a non-resizeble task in docked stack or if the task size - // is affected by the docked stack changing size. If so, instead of resizing, we - // can only scroll the task. No need to update configuration. - if (bounds != null && !task.mResizeable + // We allow the task to scroll instead of resizing if this is a non-resizeable task + // in crop windows resize mode or if the task size is affected by the docked stack + // changing size. No need to update configuration. + if (bounds != null && task.inCropWindowsResizeMode() && mStackSupervisor.isStackDockedInEffect(stackId)) { mWindowManager.scrollTask(task.taskId, bounds); return; @@ -12164,6 +12164,7 @@ public final class ActivityManagerService extends ActivityManagerNative mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; mAlwaysFinishActivities = alwaysFinishActivities; mForceResizableActivities = forceResizable; + mWindowManager.setForceResizableTasks(mForceResizableActivities); mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable; mSupportsPictureInPicture = supportsPictureInPicture || forceResizable; // This happens before any activities are started, so we can diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index d1fcd3b9dfff..133ac385260e 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -19,8 +19,6 @@ package com.android.server.am; import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; -import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE; @@ -758,18 +756,13 @@ final class ActivityRecord { } boolean isResizeable() { - return !isHomeActivity() && (info.resizeMode == RESIZE_MODE_RESIZEABLE - || info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE); + return !isHomeActivity() && ActivityInfo.isResizeableMode(info.resizeMode); } boolean supportsPictureInPicture() { return !isHomeActivity() && info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE; } - boolean cropAppWindows() { - return !isHomeActivity() && info.resizeMode == RESIZE_MODE_CROP_WINDOWS; - } - boolean isAlwaysFocusable() { return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0; } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 3e99558faf7c..dac0f7d0bd0f 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1410,10 +1410,11 @@ final class ActivityStack { } if (mStackId == DOCKED_STACK_ID) { - // Docked stack is always visible, except in the case where the top running activity in - // the focus stack doesn't support any form of resizing. + // Docked stack is always visible, except in the case where the top running activity + // task in the focus stack doesn't support any form of resizing. final ActivityRecord r = focusedStack.topRunningActivityLocked(); - return r == null || r.isResizeable() || r.cropAppWindows() + final TaskRecord task = r != null ? r.task : null; + return task == null || task.isResizeable() || task.inCropWindowsResizeMode() ? STACK_VISIBLE : STACK_INVISIBLE; } @@ -4751,7 +4752,7 @@ final class ActivityStack { // add the task to stack first, mTaskPositioner might need the stack association addTask(task, toTop, "createTaskRecord"); final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN; - if (!layoutTaskInStack(task, info.layout) && mBounds != null && task.mResizeable + if (!layoutTaskInStack(task, info.layout) && mBounds != null && task.isResizeable() && !isLockscreenShown) { task.updateOverrideConfiguration(mBounds); } @@ -4816,8 +4817,7 @@ final class ActivityStack { r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind, bounds, task.mOverrideConfig, - r.cropAppWindows() | r.isResizeable(), r.isAlwaysFocusable()); - mWindowManager.setTaskResizeable(task.taskId, task.mResizeable); + task.mResizeMode, r.isAlwaysFocusable(), task.isHomeTask()); r.taskConfigOverride = task.mOverrideConfig; } @@ -4869,9 +4869,8 @@ final class ActivityStack { private void setAppTask(ActivityRecord r, TaskRecord task) { final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds(); - mWindowManager.setAppTask( - r.appToken, task.taskId, mStackId, bounds, task.mOverrideConfig); - mWindowManager.setTaskResizeable(task.taskId, task.mResizeable); + mWindowManager.setAppTask(r.appToken, task.taskId, mStackId, bounds, task.mOverrideConfig, + task.mResizeMode, task.isHomeTask()); 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 11dd8a38cdbf..1660ddafc4f0 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -119,6 +119,7 @@ import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; +import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; @@ -1713,7 +1714,7 @@ public final class ActivityStackSupervisor implements DisplayListener { return; } - if (task.mResizeable && options != null) { + if (task.isResizeable() && options != null) { int stackId = options.getLaunchStackId(); if (canUseActivityOptionsLaunchBounds(options, stackId)) { final Rect bounds = TaskRecord.validateBounds(options.getLaunchBounds()); @@ -1895,10 +1896,10 @@ public final class ActivityStackSupervisor implements DisplayListener { mTmpBounds.clear(); mTmpConfigs.clear(); mTmpInsetBounds.clear(); - ArrayList<TaskRecord> tasks = stack.getAllTasks(); + final ArrayList<TaskRecord> tasks = stack.getAllTasks(); for (int i = tasks.size() - 1; i >= 0; i--) { - TaskRecord task = tasks.get(i); - if (task.mResizeable) { + 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 @@ -2010,7 +2011,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow) { - if (!task.mResizeable) { + if (!task.isResizeable()) { Slog.w(TAG, "resizeTask: task " + task + " not resizeable."); return true; } @@ -2189,13 +2190,13 @@ public final class ActivityStackSupervisor implements DisplayListener { final boolean wasFront = isFrontStack(prevStack) && (prevStack.topRunningActivityLocked() == r); - final boolean resizeable = task.mResizeable; + final int resizeMode = task.mResizeMode; // Temporarily disable resizeablility of task we are moving. We don't want it to be resized // if a docked stack is created below which will lead to the stack we are moving from and // its resizeable tasks being resized. - task.mResizeable = false; + task.mResizeMode = RESIZE_MODE_UNRESIZEABLE; final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, toTop); - task.mResizeable = resizeable; + task.mResizeMode = resizeMode; mWindowManager.moveTaskToStack(task.taskId, stack.mStackId, toTop); stack.addTask(task, toTop, reason); @@ -2266,7 +2267,7 @@ public final class ActivityStackSupervisor implements DisplayListener { ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); - if (!task.mResizeable && isStackDockedInEffect(stackId)) { + if (!task.isResizeable() && isStackDockedInEffect(stackId)) { showNonResizeableDockToast(taskId); } } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 7b7359f5ee1e..22b846246b7e 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1004,7 +1004,7 @@ class ActivityStarter { } mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); - if (!mStartActivity.task.mResizeable + if (!mStartActivity.task.isResizeable() && mSupervisor.isStackDockedInEffect(mTargetStack.mStackId)) { mSupervisor.showNonResizeableDockToast(mStartActivity.task.taskId); } @@ -1721,7 +1721,7 @@ class ActivityStarter { Rect getOverrideBounds(ActivityRecord r, ActivityOptions options, TaskRecord inTask) { Rect newBounds = null; - if (options != null && (r.isResizeable() || (inTask != null && inTask.mResizeable))) { + if (options != null && (r.isResizeable() || (inTask != null && inTask.isResizeable()))) { if (mSupervisor.canUseActivityOptionsLaunchBounds( options, options.getLaunchStackId())) { newBounds = TaskRecord.validateBounds(options.getLaunchBounds()); diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index c9d4595cd8cd..c14cfefbccac 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -24,8 +24,9 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_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.RESIZE_MODE_CROP_WINDOWS; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE; +import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; @@ -118,7 +119,10 @@ final class TaskRecord { private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color"; private static final String ATTR_CALLING_UID = "calling_uid"; private static final String ATTR_CALLING_PACKAGE = "calling_package"; + // TODO(b/26847884): Currently needed while migrating to resize_mode. + // Can be removed at some later point. private static final String ATTR_RESIZEABLE = "resizeable"; + private static final String ATTR_RESIZE_MODE = "resize_mode"; private static final String ATTR_PRIVILEGED = "privileged"; private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds"; @@ -156,8 +160,8 @@ final class TaskRecord { int numFullscreen; // Number of fullscreen activities. - boolean mResizeable; // Activities in the task resizeable. Based on the resizable setting of - // the root activity. + int mResizeMode; // The resize mode of this task and its activities. + // Based on the {@link ActivityInfo#resizeMode} of the root activity. int mLockTaskMode; // Which tasklock mode to launch this task in. One of // ActivityManager.LOCK_TASK_LAUNCH_MODE_* private boolean mPrivileged; // The root activity application of this task holds @@ -309,7 +313,7 @@ final class TaskRecord { boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription, TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage, - boolean resizeable, boolean privileged, boolean realActivitySuspended) { + int resizeMode, boolean privileged, boolean _realActivitySuspended) { mService = service; mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX + TaskPersister.IMAGE_EXTENSION; @@ -323,7 +327,7 @@ final class TaskRecord { voiceSession = null; voiceInteractor = null; realActivity = _realActivity; - realActivitySuspended = realActivitySuspended; + realActivitySuspended = _realActivitySuspended; origActivity = _origActivity; rootWasReset = _rootWasReset; isAvailable = true; @@ -346,7 +350,7 @@ final class TaskRecord { mNextAffiliateTaskId = nextTaskId; mCallingUid = callingUid; mCallingPackage = callingPackage; - mResizeable = resizeable || mService.mForceResizableActivities; + mResizeMode = resizeMode; mPrivileged = privileged; ActivityInfo info = (mActivities.size() > 0) ? mActivities.get(0).info : null; mMinimalSize = info != null && info.layout != null ? info.layout.minimalSize : -1; @@ -448,9 +452,7 @@ final class TaskRecord { } else { autoRemoveRecents = false; } - mResizeable = info.resizeMode == RESIZE_MODE_RESIZEABLE - || info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE - || mService.mForceResizableActivities; + mResizeMode = info.resizeMode; mLockTaskMode = info.lockTaskLaunchMode; mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0; setLockTaskAuth(); @@ -705,9 +707,6 @@ final class TaskRecord { // Only set this based on the first activity if (mActivities.isEmpty()) { taskType = r.mActivityType; - if (taskType == HOME_ACTIVITY_TYPE && mService.mForceResizableActivities) { - mResizeable = r.isResizeable(); - } isPersistable = r.isPersistable(); mCallingUid = r.launchedFromUid; mCallingPackage = r.launchedFromPackage; @@ -935,6 +934,15 @@ final class TaskRecord { return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE; } + boolean isResizeable() { + return !isHomeTask() && (mService.mForceResizableActivities + || ActivityInfo.isResizeableMode(mResizeMode)); + } + + boolean inCropWindowsResizeMode() { + return !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS; + } + /** * Find the activity in the history stack within the given task. Returns * the index within the history at which it's found, or < 0 if not found. @@ -1073,7 +1081,7 @@ final class TaskRecord { out.attribute(null, ATTR_NEXT_AFFILIATION, String.valueOf(mNextAffiliateTaskId)); out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid)); out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage); - out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable)); + out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode)); out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged)); if (mLastNonFullscreenBounds != null) { out.attribute( @@ -1139,7 +1147,7 @@ final class TaskRecord { int nextTaskId = INVALID_TASK_ID; int callingUid = -1; String callingPackage = ""; - boolean resizeable = false; + int resizeMode = RESIZE_MODE_UNRESIZEABLE; boolean privileged = false; Rect bounds = null; @@ -1200,7 +1208,10 @@ final class TaskRecord { } else if (ATTR_CALLING_PACKAGE.equals(attrName)) { callingPackage = attrValue; } else if (ATTR_RESIZEABLE.equals(attrName)) { - resizeable = Boolean.valueOf(attrValue); + resizeMode = Boolean.valueOf(attrValue) + ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_CROP_WINDOWS; + } else if (ATTR_RESIZE_MODE.equals(attrName)) { + resizeMode = Integer.valueOf(attrValue); } else if (ATTR_PRIVILEGED.equals(attrName)) { privileged = Boolean.valueOf(attrValue); } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) { @@ -1264,7 +1275,7 @@ final class TaskRecord { autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription, activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity, taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId, - taskAffiliationColor, callingUid, callingPackage, resizeable, privileged, + taskAffiliationColor, callingUid, callingPackage, resizeMode, privileged, realActivitySuspended); task.updateOverrideConfiguration(bounds); @@ -1404,7 +1415,7 @@ final class TaskRecord { } if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) { - if (!mResizeable) { + if (!isResizeable()) { throw new IllegalArgumentException("Can not position non-resizeable task=" + this + " in stack=" + inStack); } @@ -1450,8 +1461,8 @@ final class TaskRecord { final int stackId = stack.mStackId; if (stackId == HOME_STACK_ID || stackId == FULLSCREEN_WORKSPACE_STACK_ID - || (stackId == DOCKED_STACK_ID && !mResizeable)) { - return mResizeable ? stack.mBounds : null; + || (stackId == DOCKED_STACK_ID && !isResizeable())) { + return isResizeable() ? stack.mBounds : null; } else if (!StackId.persistTaskBounds(stackId)) { return stack.mBounds; } @@ -1554,12 +1565,12 @@ final class TaskRecord { if (stack != null) { pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId); } - pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible); - pw.print(" mResizeable="); pw.print(mResizeable); - pw.print(" firstActiveTime="); pw.print(lastActiveTime); - pw.print(" lastActiveTime="); pw.print(lastActiveTime); - pw.print(" (inactive for "); - pw.print((getInactiveDuration()/1000)); pw.println("s)"); + pw.print(prefix + "hasBeenVisible=" + hasBeenVisible); + pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode)); + pw.print(" isResizeable=" + isResizeable()); + pw.print(" firstActiveTime=" + lastActiveTime); + pw.print(" lastActiveTime=" + lastActiveTime); + pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)"); } @Override diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 27328216b45e..c0d34e87fd04 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -125,9 +125,6 @@ class AppWindowToken extends WindowToken { boolean mLaunchTaskBehind; boolean mEnteringAnimation; - // True if the windows associated with this token should be cropped to their stack bounds. - boolean mCropWindowsToStack; - boolean mAlwaysFocusable; ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>(); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index d9667a1225ff..4f59c62b5c40 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -21,6 +21,7 @@ import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION; +import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; @@ -32,6 +33,7 @@ import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_TOP; import android.app.ActivityManager.StackId; +import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.util.EventLog; @@ -84,8 +86,8 @@ class Task implements DimLayer.DimLayerUser { // For handling display rotations. private Rect mTmpRect2 = new Rect(); - // Whether the task is resizeable - private boolean mResizeable; + // Resize mode of the task. See {@link ActivityInfo#resizeMode} + private int mResizeMode; // Whether we need to show toast about the app being non-resizeable when it becomes visible. // This flag is set when a non-resizeable task is docked (or side-by-side). It's cleared @@ -95,6 +97,8 @@ class Task implements DimLayer.DimLayerUser { // Whether the task is currently being drag-resized private boolean mDragResizing; + private boolean mHomeTask; + Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds, Configuration config) { mTaskId = taskId; @@ -156,7 +160,7 @@ class Task implements DimLayer.DimLayerUser { } } - void addAppToken(int addPos, AppWindowToken wtoken) { + void addAppToken(int addPos, AppWindowToken wtoken, int resizeMode, boolean homeTask) { final int lastPos = mAppTokens.size(); if (addPos >= lastPos) { addPos = lastPos; @@ -171,6 +175,8 @@ class Task implements DimLayer.DimLayerUser { mAppTokens.add(addPos, wtoken); wtoken.mTask = this; mDeferRemoval = false; + mResizeMode = resizeMode; + mHomeTask = homeTask; } private boolean hasAppTokensAlive() { @@ -319,12 +325,21 @@ class Task implements DimLayer.DimLayerUser { out.set(mTempInsetBounds); } - void setResizeable(boolean resizeable) { - mResizeable = resizeable; + void setResizeable(int resizeMode) { + mResizeMode = resizeMode; } boolean isResizeable() { - return mResizeable; + return !mHomeTask + && (ActivityInfo.isResizeableMode(mResizeMode) || mService.mForceResizableTasks); + } + + boolean cropWindowsToStackBounds() { + return !mHomeTask && (isResizeable() || mResizeMode == RESIZE_MODE_CROP_WINDOWS); + } + + private boolean inCropWindowsResizeMode() { + return !mHomeTask && !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS; } boolean resizeLocked(Rect bounds, Configuration configuration, boolean forced) { @@ -619,7 +634,7 @@ class Task implements DimLayer.DimLayerUser { } boolean isTwoFingerScrollMode() { - return isDockedInEffect() && !isResizeable(); + return inCropWindowsResizeMode() && isDockedInEffect(); } WindowState getTopVisibleAppMainWindow() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index e0e44dc4799f..22528d616b9f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -492,6 +492,8 @@ public class WindowManagerService extends IWindowManager.Stub private final SparseIntArray mTmpTaskIds = new SparseIntArray(); + boolean mForceResizableTasks = false; + int getDragLayerLocked() { return mPolicy.windowTypeToLayerLw(LayoutParams.TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; @@ -3214,8 +3216,8 @@ public class WindowManagerService extends IWindowManager.Stub 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, Configuration config, boolean cropWindowsToStack, - boolean alwaysFocusable) { + Rect taskBounds, Configuration config, int taskResizeMode, boolean alwaysFocusable, + boolean homeTask) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "addAppToken()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); @@ -3249,7 +3251,6 @@ public class WindowManagerService extends IWindowManager.Stub atoken.layoutConfigChanges = (configChanges & (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0; atoken.mLaunchTaskBehind = launchTaskBehind; - atoken.mCropWindowsToStack = cropWindowsToStack; atoken.mAlwaysFocusable = alwaysFocusable; if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken + " to stack=" + stackId + " task=" + taskId + " at " + addPos); @@ -3258,7 +3259,7 @@ public class WindowManagerService extends IWindowManager.Stub if (task == null) { task = createTaskLocked(taskId, stackId, userId, atoken, taskBounds, config); } - task.addAppToken(addPos, atoken); + task.addAppToken(addPos, atoken, taskResizeMode, homeTask); mTokenMap.put(token.asBinder(), atoken); @@ -3269,8 +3270,8 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void setAppTask( - IBinder token, int taskId, int stackId, Rect taskBounds, Configuration config) { + public void setAppTask(IBinder token, int taskId, int stackId, Rect taskBounds, + Configuration config, int taskResizeMode, boolean homeTask) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "setAppTask()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); @@ -3290,7 +3291,7 @@ public class WindowManagerService extends IWindowManager.Stub newTask = createTaskLocked( taskId, stackId, oldTask.mUserId, atoken, taskBounds, config); } - newTask.addAppToken(Integer.MAX_VALUE /* at top */, atoken); + newTask.addAppToken(Integer.MAX_VALUE /* at top */, atoken, taskResizeMode, homeTask); } } @@ -10326,15 +10327,21 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void setTaskResizeable(int taskId, boolean resizeable) { + public void setTaskResizeable(int taskId, int resizeMode) { synchronized (mWindowMap) { - Task task = mTaskIdToTask.get(taskId); + final Task task = mTaskIdToTask.get(taskId); if (task != null) { - task.setResizeable(resizeable); + task.setResizeable(resizeMode); } } } + public void setForceResizableTasks(boolean forceResizableTasks) { + synchronized (mWindowMap) { + mForceResizableTasks = forceResizableTasks; + } + } + static int dipToPixel(int dip, DisplayMetrics displayMetrics) { return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 4dd2b4dfa9ad..10a2a6ca4487 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1002,11 +1002,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { * @param bounds The rect which gets the bounds. */ void getVisibleBounds(Rect bounds) { - boolean intersectWithStackBounds = mAppToken != null && mAppToken.mCropWindowsToStack; + final Task task = getTask(); + boolean intersectWithStackBounds = task != null && task.cropWindowsToStackBounds(); bounds.setEmpty(); mTmpRect.setEmpty(); if (intersectWithStackBounds) { - final TaskStack stack = getStack(); + final TaskStack stack = task.mStack; if (stack != null) { stack.getDimBounds(mTmpRect); } else { @@ -1932,11 +1933,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { } void cropRegionToStackBoundsIfNeeded(Region region) { - if (mAppToken == null || !mAppToken.mCropWindowsToStack) { + final Task task = getTask(); + if (task == null || !task.cropWindowsToStackBounds()) { return; } - final TaskStack stack = getStack(); + final TaskStack stack = task.mStack; if (stack == null) { return; } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 428ab7a5eb5d..d21a3b455dea 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1171,9 +1171,8 @@ class WindowStateAnimator { } private void adjustCropToStackBounds(WindowState w, Rect clipRect, boolean isFreeformResizing) { - final AppWindowToken appToken = w.mAppToken; final Task task = w.getTask(); - if (task == null || !appToken.mCropWindowsToStack) { + if (task == null || !task.cropWindowsToStackBounds()) { return; } 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 b78fd494e555..0286506cd3d8 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -93,7 +93,7 @@ public class WindowManagerPermissionTests extends TestCase { try { mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false, null, - Configuration.EMPTY, false, false); + Configuration.EMPTY, 0, false, false); fail("IWindowManager.addAppToken did not throw SecurityException as" + " expected"); } catch (SecurityException e) { @@ -103,7 +103,7 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.setAppTask(null, 0, INVALID_STACK_ID, null, null); + mWm.setAppTask(null, 0, INVALID_STACK_ID, null, null, 0, false); fail("IWindowManager.setAppGroupId did not throw SecurityException as" + " expected"); } catch (SecurityException e) { diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 9f0153a09c70..38eb5ee25eb3 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -77,7 +77,8 @@ public class IWindowManagerImpl implements IWindowManager { @Override public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, int arg4, boolean arg5, boolean arg6, int arg7, int arg8, boolean arg9, boolean arg10, - Rect arg11, Configuration arg12, boolean arg13, boolean arg14) throws RemoteException { + Rect arg11, Configuration arg12, int arg13, boolean arg14, boolean arg15) + throws RemoteException { // TODO Auto-generated method stub } @@ -322,7 +323,8 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public void setAppTask(IBinder arg0, int arg1, int arg2, Rect arg3, Configuration arg4) + public void setAppTask(IBinder arg0, int arg1, int arg2, Rect arg3, Configuration arg4, + int arg5, boolean arg6) throws RemoteException { // TODO Auto-generated method stub } |