diff options
5 files changed, 116 insertions, 59 deletions
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index dedf07f5dcff..91a8e0a96191 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -156,6 +156,35 @@ public class ActivityInfo extends ComponentInfo public String targetActivity; /** + * Activity can not be resized and always occupies the fullscreen area with all windows fully + * visible. + * @hide + */ + public static final int RESIZE_MODE_UNRESIZEABLE = 0; + /** + * Activity can not be resized and always occupies the fullscreen area with all windows cropped + * to either the task or stack bounds. + * @hide + */ + public static final int RESIZE_MODE_CROP_WINDOWS = 1; + /** + * Activity is resizeable. + * @hide + */ + public static final int RESIZE_MODE_RESIZEABLE = 2; + /** + * Activity is resizeable and supported picture-in-picture mode. + * @hide + */ + public static final int RESIZE_MODE_RESIZEABLE_AND_PIPABLE = 3; + /** + * Value indicating if the resizing mode the activity supports. + * See {@link android.R.attr#resizeableActivity}. + * @hide + */ + public int resizeMode; + + /** * Bit in {@link #flags} indicating whether this activity is able to * run in multiple processes. If * true, the system may instantiate it in the some process as the @@ -283,20 +312,6 @@ public class ActivityInfo extends ComponentInfo public static final int FLAG_ENABLE_VR_MODE = 0x8000; /** - * Bit in {@link #flags} indicating if the activity is resizeable to any dimension. - * See {@link android.R.attr#resizeableActivity}. - * @hide - */ - public static final int FLAG_RESIZEABLE = 0x10000; - - /** - * Bit in {@link #flags} indicating if the activity is supports picture-in-picture form of - * multi-window mode. See {@link android.R.attr#supportsPictureInPicture}. - * @hide - */ - public static final int FLAG_SUPPORTS_PICTURE_IN_PICTURE = 0x20000; - - /** * Bit in {@link #flags} indicating if the activity is always focusable regardless of if it is * in a task/stack whose activities are normally not focusable. * See android.R.attr#alwaysFocusable. @@ -746,6 +761,7 @@ public class ActivityInfo extends ComponentInfo maxRecents = orig.maxRecents; lockTaskLaunchMode = orig.lockTaskLaunchMode; layout = orig.layout; + resizeMode = orig.resizeMode; } /** @@ -768,6 +784,22 @@ public class ActivityInfo extends ComponentInfo } } + /** @hide */ + public static final String resizeModeToString(int mode) { + switch (mode) { + case RESIZE_MODE_UNRESIZEABLE: + return "RESIZE_MODE_UNRESIZEABLE"; + case RESIZE_MODE_CROP_WINDOWS: + return "RESIZE_MODE_CROP_WINDOWS"; + case RESIZE_MODE_RESIZEABLE: + return "RESIZE_MODE_RESIZEABLE"; + case RESIZE_MODE_RESIZEABLE_AND_PIPABLE: + return "RESIZE_MODE_RESIZEABLE_AND_PIPABLE"; + default: + return "unknown=" + mode; + } + } + public void dump(Printer pw, String prefix) { dump(pw, prefix, DUMP_FLAG_ALL); } @@ -806,6 +838,7 @@ public class ActivityInfo extends ComponentInfo + layout.widthFraction + ", " + layout.height + "|" + layout.heightFraction + ", " + layout.gravity); } + pw.println(prefix + "resizeMode=" + resizeModeToString(resizeMode)); super.dumpBack(pw, prefix, flags); } @@ -847,6 +880,7 @@ public class ActivityInfo extends ComponentInfo } else { dest.writeInt(0); } + dest.writeInt(resizeMode); } public static final Parcelable.Creator<ActivityInfo> CREATOR @@ -879,6 +913,7 @@ public class ActivityInfo extends ComponentInfo if (source.readInt() == 1) { layout = new Layout(source); } + resizeMode = source.readInt(); } public static final class Layout { diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index a6fec9f3f67b..9319c2ec99d1 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -16,15 +16,12 @@ package android.content.pm; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; -import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; -import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; +import com.android.internal.R; +import com.android.internal.util.ArrayUtils; +import com.android.internal.util.XmlUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import android.app.ActivityManager; import android.content.ComponentName; @@ -55,15 +52,6 @@ import android.util.apk.ApkSignatureSchemeV2Verifier; import android.util.jar.StrictJarFile; import android.view.Gravity; -import com.android.internal.R; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.XmlUtils; - -import libcore.io.IoUtils; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -87,6 +75,25 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.zip.ZipEntry; +import libcore.io.IoUtils; + +import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; +import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE; +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.SCREEN_ORIENTATION_UNSPECIFIED; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; +import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; + /** * Parser for package files (APKs) on disk. This supports apps packaged either * as a single "monolithic" APK, or apps packaged as a "cluster" of multiple @@ -3219,24 +3226,29 @@ public class PackageParser { a.info.flags |= ActivityInfo.FLAG_RESUME_WHILE_PAUSING; } - if (sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity, - owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N)) { - a.info.flags |= ActivityInfo.FLAG_RESIZEABLE; - - if (sa.getBoolean(R.styleable.AndroidManifestActivity_supportsPictureInPicture, - false)) { - a.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE; + a.info.screenOrientation = sa.getInt( + R.styleable.AndroidManifestActivity_screenOrientation, + SCREEN_ORIENTATION_UNSPECIFIED); + + a.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; + if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) { + if (sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity, true)) { + if (sa.getBoolean(R.styleable.AndroidManifestActivity_supportsPictureInPicture, + false)) { + a.info.resizeMode = RESIZE_MODE_RESIZEABLE_AND_PIPABLE; + } else { + a.info.resizeMode = RESIZE_MODE_RESIZEABLE; + } } + } else if (a.info.screenOrientation == SCREEN_ORIENTATION_UNSPECIFIED + && (a.info.flags & FLAG_IMMERSIVE) == 0) { + a.info.resizeMode = RESIZE_MODE_CROP_WINDOWS; } if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysFocusable, false)) { - a.info.flags |= ActivityInfo.FLAG_ALWAYS_FOCUSABLE; + a.info.flags |= FLAG_ALWAYS_FOCUSABLE; } - a.info.screenOrientation = sa.getInt( - R.styleable.AndroidManifestActivity_screenOrientation, - ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - a.info.lockTaskLaunchMode = sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0); @@ -3478,6 +3490,7 @@ public class PackageParser { info.parentActivityName = target.info.parentActivityName; info.maxRecents = target.info.maxRecents; info.layout = target.info.layout; + info.resizeMode = target.info.resizeMode; Activity a = new Activity(mParseActivityAliasArgs, info); if (outError[0] != null) { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 71008a9e8141..d1fcd3b9dfff 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -19,8 +19,9 @@ 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.FLAG_RESIZEABLE; -import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE; +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; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; @@ -355,6 +356,9 @@ final class ActivityRecord { if (connections != null) { pw.print(prefix); pw.print("connections="); pw.println(connections); } + if (info != null) { + pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode)); + } } public boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) { @@ -754,11 +758,16 @@ final class ActivityRecord { } boolean isResizeable() { - return (info.flags & FLAG_RESIZEABLE) != 0; + return !isHomeActivity() && (info.resizeMode == RESIZE_MODE_RESIZEABLE + || info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE); } boolean supportsPictureInPicture() { - return (info.flags & FLAG_SUPPORTS_PICTURE_IN_PICTURE) != 0; + return !isHomeActivity() && info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE; + } + + boolean cropAppWindows() { + return !isHomeActivity() && info.resizeMode == RESIZE_MODE_CROP_WINDOWS; } boolean isAlwaysFocusable() { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index ef8d2305fb2b..3e99558faf7c 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1410,14 +1410,11 @@ final class ActivityStack { } if (mStackId == DOCKED_STACK_ID) { - // Docked stack is always visible, except in the case where the home activity - // is the top running activity in the focused home stack. - if (focusedStackId != HOME_STACK_ID) { - return STACK_VISIBLE; - } - ActivityRecord topHomeActivity = focusedStack.topRunningActivityLocked(); - return topHomeActivity == null || !topHomeActivity.isHomeActivity() ? - STACK_VISIBLE : STACK_INVISIBLE; + // 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. + final ActivityRecord r = focusedStack.topRunningActivityLocked(); + return r == null || r.isResizeable() || r.cropAppWindows() + ? STACK_VISIBLE : STACK_INVISIBLE; } // Find the first stack below focused stack that actually got something visible. @@ -4819,7 +4816,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.isHomeActivity(), r.isAlwaysFocusable()); + r.cropAppWindows() | r.isResizeable(), r.isAlwaysFocusable()); mWindowManager.setTaskResizeable(task.taskId, task.mResizeable); r.taskConfigOverride = task.mOverrideConfig; } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index fd787df25115..c9d4595cd8cd 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -24,7 +24,8 @@ 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.FLAG_RESIZEABLE; +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.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; @@ -447,7 +448,9 @@ final class TaskRecord { } else { autoRemoveRecents = false; } - mResizeable = (info.flags & FLAG_RESIZEABLE) != 0 || mService.mForceResizableActivities; + mResizeable = info.resizeMode == RESIZE_MODE_RESIZEABLE + || info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE + || mService.mForceResizableActivities; mLockTaskMode = info.lockTaskLaunchMode; mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0; setLockTaskAuth(); |