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
This commit is contained in:
Louis Chang
2021-02-20 15:05:30 +08:00
parent ca5181f90a
commit 8846e4d089
6 changed files with 62 additions and 6 deletions

View File

@@ -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 <code>singleInstancePerTask</code> 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;
/**

View File

@@ -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.

View File

@@ -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<ActivityInfo.WindowLayout> layoutResult =
resolveActivityWindowLayout(activity, input);
if (layoutResult.isError()) {