Merge "Support different multi-window compatibility modes"
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index dedf07f5..91a8e0a 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -156,6 +156,35 @@
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 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 @@
maxRecents = orig.maxRecents;
lockTaskLaunchMode = orig.lockTaskLaunchMode;
layout = orig.layout;
+ resizeMode = orig.resizeMode;
}
/**
@@ -768,6 +784,22 @@
}
}
+ /** @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 @@
+ layout.widthFraction + ", " + layout.height + "|"
+ layout.heightFraction + ", " + layout.gravity);
}
+ pw.println(prefix + "resizeMode=" + resizeModeToString(resizeMode));
super.dumpBack(pw, prefix, flags);
}
@@ -847,6 +880,7 @@
} else {
dest.writeInt(0);
}
+ dest.writeInt(resizeMode);
}
public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -879,6 +913,7 @@
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 a6fec9f..9319c2e 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.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.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 @@
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;
+ a.info.screenOrientation = sa.getInt(
+ R.styleable.AndroidManifestActivity_screenOrientation,
+ SCREEN_ORIENTATION_UNSPECIFIED);
- if (sa.getBoolean(R.styleable.AndroidManifestActivity_supportsPictureInPicture,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+ 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 @@
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 71008a9..d1fcd3b 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 @@
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 @@
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 @@
}
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 ef8d230..3e99558 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 @@
}
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 @@
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 fd787df..c9d4595 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.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 @@
} 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();