From c5bf49474f9b7ed242b8ccff8ba56f62356a34d7 Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Wed, 4 Aug 2021 17:36:50 -0700 Subject: [PATCH] Expose ActivityOptions.fromBundle() as ModuleApi. CarService mainline module will use it. Changed to accept NonNull only. Bug: 195598146 Test: atest android.app.cts.ActivityOptionsTest Change-Id: Iae70522fe1ad8b17a01c230ca8afb7a18b83a7ed --- core/api/module-lib-current.txt | 4 ++++ core/api/test-current.txt | 1 + core/java/android/app/ActivityOptions.java | 15 ++++++++++++--- .../app/servertransaction/LaunchActivityItem.java | 7 ++++++- .../app/servertransaction/StartActivityItem.java | 4 +++- .../android/server/am/PendingIntentRecord.java | 3 ++- .../android/server/pm/LauncherAppsService.java | 12 +++++++----- 7 files changed, 35 insertions(+), 11 deletions(-) diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 5b72b027aa9fc..e11096912e919 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -15,6 +15,10 @@ package android.app { method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String); } + public class ActivityOptions { + method @NonNull public static android.app.ActivityOptions fromBundle(@NonNull android.os.Bundle); + } + public class AppOpsManager { field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage"; } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 56c14fc3927ec..6b0abb74c05a9 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -140,6 +140,7 @@ package android.app { } public class ActivityOptions { + method @NonNull public static android.app.ActivityOptions fromBundle(@NonNull android.os.Bundle); method @NonNull public static android.app.ActivityOptions makeCustomAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener); method @NonNull @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) public static android.app.ActivityOptions makeCustomTaskAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener); method public static void setExitTransitionTimeout(long); diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 76f873185267a..82d6e9d1c17fd 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -26,6 +26,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ExitTransitionCoordinator.ActivityExitTransitionCallbacks; import android.app.ExitTransitionCoordinator.ExitTransitionCallbacks; @@ -1352,9 +1353,17 @@ public class ActivityOptions { return mRemoteTransition; } - /** @hide */ - public static ActivityOptions fromBundle(Bundle bOptions) { - return bOptions != null ? new ActivityOptions(bOptions) : null; + /** + * Creates an ActivityOptions from the Bundle generated from {@link ActivityOptions#toBundle()}. + * Returns an instance of ActivityOptions populated with options with known keys from the + * provided Bundle, stripping out unknown entries. + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @TestApi + @NonNull + public static ActivityOptions fromBundle(@NonNull Bundle bOptions) { + return new ActivityOptions(bOptions); } /** @hide */ diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index 37cbccb897358..019d5ba39b356 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -187,7 +187,7 @@ public class LaunchActivityItem extends ClientTransactionItem { in.readPersistableBundle(getClass().getClassLoader()), in.createTypedArrayList(ResultInfo.CREATOR), in.createTypedArrayList(ReferrerIntent.CREATOR), - ActivityOptions.fromBundle(in.readBundle()), in.readBoolean(), + readActivityOptions(in), in.readBoolean(), in.readTypedObject(ProfilerInfo.CREATOR), in.readStrongBinder(), IActivityClientController.Stub.asInterface(in.readStrongBinder()), @@ -196,6 +196,11 @@ public class LaunchActivityItem extends ClientTransactionItem { in.readStrongBinder()); } + private static ActivityOptions readActivityOptions(Parcel in) { + Bundle bundle = in.readBundle(); + return bundle != null ? ActivityOptions.fromBundle(bundle) : null; + } + public static final @NonNull Creator CREATOR = new Creator() { public LaunchActivityItem createFromParcel(Parcel in) { diff --git a/core/java/android/app/servertransaction/StartActivityItem.java b/core/java/android/app/servertransaction/StartActivityItem.java index 15f65f6d9d26b..f267060d1be6c 100644 --- a/core/java/android/app/servertransaction/StartActivityItem.java +++ b/core/java/android/app/servertransaction/StartActivityItem.java @@ -23,6 +23,7 @@ import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; +import android.os.Bundle; import android.os.Parcel; import android.os.Trace; @@ -83,7 +84,8 @@ public class StartActivityItem extends ActivityLifecycleItem { /** Read from Parcel. */ private StartActivityItem(Parcel in) { - mActivityOptions = ActivityOptions.fromBundle(in.readBundle()); + Bundle bundle = in.readBundle(); + mActivityOptions = bundle != null ? ActivityOptions.fromBundle(bundle) : null; } public static final @NonNull Creator CREATOR = diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 175da9cab77be..d610b909c40d1 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -352,7 +352,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { // Apply any launch flags from the ActivityOptions. This is to ensure that the caller // can specify a consistent launch mode even if the PendingIntent is immutable - final ActivityOptions opts = ActivityOptions.fromBundle(options); + final ActivityOptions opts = options != null ? ActivityOptions.fromBundle(options) + : null; if (opts != null) { finalIntent.addFlags(opts.getPendingIntentLaunchFlags()); } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 6f02138bbab61..edaae47298ef3 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -995,11 +995,13 @@ public class LauncherAppsService extends SystemService { // Note the target activity doesn't have to be exported. // Flag for bubble - ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions); - if (options != null && options.isApplyActivityFlagsForBubbles()) { - // Flag for bubble to make behaviour match documentLaunchMode=always. - intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT); - intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + if (startActivityOptions != null) { + ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions); + if (options.isApplyActivityFlagsForBubbles()) { + // Flag for bubble to make behaviour match documentLaunchMode=always. + intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT); + intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK); + } } intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);