From 8846e4d0899e69b110d28dd4dfb7c33fb0e87407 Mon Sep 17 00:00:00 2001 From: Louis Chang Date: Sat, 20 Feb 2021 15:05:30 +0800 Subject: [PATCH] New activity launch mode - singleInstancePerTask Adding a new activity launch mode `singleInstancePerTask` which is similar to singleTask that the activity is single instance and can only be created in task root, but still allowed to be created in multiple documents or tasks. Also adding meta-data support of apps that targeting on previous SDK. Bug: 175354896 Test: IntentTests Change-Id: I4ba3b2ba6d619677f03e67d3b7da1b5d2a79907f --- core/api/current.txt | 1 + .../java/android/content/pm/ActivityInfo.java | 26 +++++++++++++++---- .../android/content/pm/PackageParser.java | 1 + .../component/ParsedActivityUtils.java | 12 +++++++++ core/res/res/values/attrs_manifest.xml | 6 +++++ .../android/server/wm/ActivityStarter.java | 22 +++++++++++++++- 6 files changed, 62 insertions(+), 6 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index b1e8645a2ae33..469bcffd0f4b2 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -11719,6 +11719,7 @@ package android.content.pm { field public static final int FLAG_STATE_NOT_NEEDED = 16; // 0x10 field public static final int LAUNCH_MULTIPLE = 0; // 0x0 field public static final int LAUNCH_SINGLE_INSTANCE = 3; // 0x3 + field public static final int LAUNCH_SINGLE_INSTANCE_PER_TASK = 4; // 0x4 field public static final int LAUNCH_SINGLE_TASK = 2; // 0x2 field public static final int LAUNCH_SINGLE_TOP = 1; // 0x1 field public static final int PERSIST_ACROSS_REBOOTS = 2; // 0x2 diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index b1ca12cde8577..1660c9d23002a 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -74,12 +74,28 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { */ public static final int LAUNCH_SINGLE_INSTANCE = 3; /** - * The launch mode style requested by the activity. From the - * {@link android.R.attr#launchMode} attribute, one of - * {@link #LAUNCH_MULTIPLE}, - * {@link #LAUNCH_SINGLE_TOP}, {@link #LAUNCH_SINGLE_TASK}, or - * {@link #LAUNCH_SINGLE_INSTANCE}. + * Constant corresponding to singleInstancePerTask in + * the {@link android.R.attr#launchMode} attribute. */ + public static final int LAUNCH_SINGLE_INSTANCE_PER_TASK = 4; + + /** @hide */ + @IntDef(prefix = "LAUNCH_", value = { + LAUNCH_MULTIPLE, + LAUNCH_SINGLE_TOP, + LAUNCH_SINGLE_TASK, + LAUNCH_SINGLE_INSTANCE, + LAUNCH_SINGLE_INSTANCE_PER_TASK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface LaunchMode { + } + + /** + * The launch mode style requested by the activity. From the + * {@link android.R.attr#launchMode} attribute. + */ + @LaunchMode public int launchMode; /** diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index bf8d1f6ab07b1..5e08399f8abb8 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -214,6 +214,7 @@ public class PackageParser { public static final String METADATA_SUPPORTS_SIZE_CHANGES = "android.supports_size_changes"; public static final String METADATA_ACTIVITY_WINDOW_LAYOUT_AFFINITY = "android.activity_window_layout_affinity"; + public static final String METADATA_ACTIVITY_LAUNCH_MODE = "android.activity.launch_mode"; /** * Bit mask of all the valid bits that can be set in recreateOnConfigChanges. diff --git a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java index f821e081fc66b..0f4aa061b72d0 100644 --- a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java @@ -16,6 +16,7 @@ package android.content.pm.parsing.component; +import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.parsing.component.ComponentParseUtils.flag; @@ -23,6 +24,7 @@ import android.annotation.NonNull; import android.app.ActivityTaskManager; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.pm.PackageParser; import android.content.pm.parsing.ParsingPackage; import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingUtils; @@ -402,6 +404,16 @@ public class ParsedActivityUtils { } } + if (!isAlias && activity.launchMode != LAUNCH_SINGLE_INSTANCE_PER_TASK + && activity.metaData != null && activity.metaData.containsKey( + PackageParser.METADATA_ACTIVITY_LAUNCH_MODE)) { + final String launchMode = activity.metaData.getString( + PackageParser.METADATA_ACTIVITY_LAUNCH_MODE); + if (launchMode != null && launchMode.equals("singleInstancePerTask")) { + activity.launchMode = LAUNCH_SINGLE_INSTANCE_PER_TASK; + } + } + ParseResult layoutResult = resolveActivityWindowLayout(activity, input); if (layoutResult.isError()) { diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index bed5c31bd3274..3c703fc47c559 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -825,6 +825,12 @@ Tasks and Back Stack document for more details about tasks.--> + +