From fb1c86439c7991237594760a957e7eba1d86df52 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Wed, 2 Mar 2016 08:28:08 -0800 Subject: [PATCH] config_supportsMultiWindow for device to specify multi-window support Devices that have the config set to false will not allow any multi-window operation. Also, added ActivityManager.supportsMultiWindow that checks the new config and also returns false if the device is a low RAM device. Bug: 27419483 Change-Id: I8dd85c17d290a5a752de3253beb3b34c17d7736d --- core/java/android/app/ActivityManager.java | 21 +++++++++++++++++++ core/res/res/values/config.xml | 4 ++++ core/res/res/values/symbols.xml | 1 + .../server/am/ActivityManagerService.java | 13 ++++++++++-- .../server/am/ActivityStackSupervisor.java | 8 +++++-- .../android/server/am/ActivityStarter.java | 9 ++++---- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 4aab163597d61..4676cc4620f09 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -647,6 +647,16 @@ public class ActivityManager { return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID && stackId != DOCKED_STACK_ID; } + + /** + * Returns true if the input stack id should only be present on a device that supports + * multi-window mode. + * @see android.app.ActivityManager#supportsMultiWindow + */ + public static boolean isMultiWindowStack(int stackId) { + return isStaticStack(stackId) || stackId == PINNED_STACK_ID + || stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == DOCKED_STACK_ID; + } } /** @@ -867,6 +877,17 @@ public class ActivityManager { return getMaxRecentTasksStatic() / 2; } + /** + * Returns true if the system supports at least one form of multi-window. + * E.g. freeform, split-screen, picture-in-picture. + * @hide + */ + static public boolean supportsMultiWindow() { + return !isLowRamDeviceStatic() + && Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_supportsMultiWindow); + } + /** * Information you can set and retrieve about the current activity within the recent task list. */ diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index b65f19b08e073..be28449e6d56d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2479,4 +2479,8 @@ handle wallpaper cropping. --> com.android.wallpapercropper + + + true diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 44a7a8d39077d..1d6838886be46 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -303,6 +303,7 @@ + diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 12ebf44cba261..9727006a6fb32 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1294,6 +1294,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean mAlwaysFinishActivities = false; boolean mLenientBackgroundCheck = false; boolean mForceResizableActivities; + boolean mSupportsMultiWindow; boolean mSupportsFreeformWindowManagement; boolean mSupportsPictureInPicture; Rect mDefaultPinnedStackBounds; @@ -12336,6 +12337,7 @@ public final class ActivityManagerService extends ActivityManagerNative final boolean supportsPictureInPicture = mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); + final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(); final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0; final boolean alwaysFinishActivities = @@ -12362,8 +12364,15 @@ public final class ActivityManagerService extends ActivityManagerNative mLenientBackgroundCheck = lenientBackgroundCheck; mForceResizableActivities = forceResizable; mWindowManager.setForceResizableTasks(mForceResizableActivities); - mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable; - mSupportsPictureInPicture = supportsPictureInPicture || forceResizable; + if (supportsMultiWindow || forceResizable) { + mSupportsMultiWindow = true; + mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable; + mSupportsPictureInPicture = supportsPictureInPicture || forceResizable; + } else { + mSupportsMultiWindow = false; + mSupportsFreeformWindowManagement = false; + mSupportsPictureInPicture = false; + } // This happens before any activities are started, so we can // change mConfiguration in-place. updateConfigurationLocked(configuration, null, true); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index c7fc5e24669a7..f92869025e208 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2174,6 +2174,12 @@ public final class ActivityStackSupervisor implements DisplayListener { */ ActivityStack moveTaskToStackUncheckedLocked( TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) { + + if (StackId.isMultiWindowStack(stackId) && !mService.mSupportsMultiWindow) { + throw new IllegalStateException("moveTaskToStackUncheckedLocked: Device doesn't " + + "support multi-window task=" + task + " to stackId=" + stackId); + } + final ActivityRecord r = task.getTopActivity(); final ActivityStack prevStack = task.stack; final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r); @@ -2184,8 +2190,6 @@ public final class ActivityStackSupervisor implements DisplayListener { final boolean wasFront = isFrontStack(prevStack) && (prevStack.topRunningActivityLocked() == r); - final int resizeMode = task.mResizeMode; - if (stackId == DOCKED_STACK_ID && !task.isResizeable()) { // We don't allow moving a unresizeable task to the docked stack since the docked // stack is used for split-screen mode and will cause things like the docked divider to diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index bcdc800c58575..46389e2ef803e 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1772,12 +1772,13 @@ class ActivityStarter { return false; } - if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) { - return true; + if (stackId != FULLSCREEN_WORKSPACE_STACK_ID + && (!mService.mSupportsMultiWindow || !r.isResizeableOrForced())) { + return false; } - if (stackId != FULLSCREEN_WORKSPACE_STACK_ID && !r.isResizeableOrForced()) { - return false; + if (stackId == DOCKED_STACK_ID && r.canGoInDockedStack()) { + return true; } if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {