diff options
| -rw-r--r-- | core/java/android/app/ActivityOptions.java | 28 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 15 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/PendingIntentRecord.java | 11 |
3 files changed, 48 insertions, 6 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 63c61d319a44..906a20f80c81 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -195,6 +195,13 @@ public class ActivityOptions { private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId"; /** + * See {@link #setPendingIntentLaunchFlags(int)} + * @hide + */ + private static final String KEY_PENDING_INTENT_LAUNCH_FLAGS = + "android.activity.pendingIntentLaunchFlags"; + + /** * See {@link #setTaskOverlay}. * @hide */ @@ -309,6 +316,7 @@ public class ActivityOptions { @WindowConfiguration.ActivityType private int mLaunchActivityType = ACTIVITY_TYPE_UNDEFINED; private int mLaunchTaskId = -1; + private int mPendingIntentLaunchFlags; private int mSplitScreenCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; private boolean mLockTaskMode = false; private boolean mDisallowEnterPictureInPictureWhileLaunching; @@ -932,6 +940,7 @@ public class ActivityOptions { mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED); mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED); mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1); + mPendingIntentLaunchFlags = opts.getInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, 0); mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false); mTaskOverlayCanResume = opts.getBoolean(KEY_TASK_OVERLAY_CAN_RESUME, false); mAvoidMoveToFront = opts.getBoolean(KEY_AVOID_MOVE_TO_FRONT, false); @@ -1233,6 +1242,22 @@ public class ActivityOptions { } /** + * Specifies intent flags to be applied for any activity started from a PendingIntent. + * + * @hide + */ + public void setPendingIntentLaunchFlags(@android.content.Intent.Flags int flags) { + mPendingIntentLaunchFlags = flags; + } + + /** + * @hide + */ + public int getPendingIntentLaunchFlags() { + return mPendingIntentLaunchFlags; + } + + /** * Set's whether the activity launched with this option should be a task overlay. That is the * activity will always be the top activity of the task. If {@param canResume} is true, then * the task will also not be moved to the front of the stack. @@ -1463,6 +1488,9 @@ public class ActivityOptions { if (mLaunchTaskId != -1) { b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId); } + if (mPendingIntentLaunchFlags != 0) { + b.putInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, mPendingIntentLaunchFlags); + } if (mTaskOverlay) { b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay); } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 35ff6cc23499..001a09dd8c21 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -368,10 +368,12 @@ public class RemoteViews implements Parcelable, Filter { // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT? Context context = view.getContext(); ActivityOptions opts = getActivityOptions(context); + // The NEW_TASK flags are applied through the activity options and not as a part of + // the call to startIntentSender() to ensure that they are consistently applied to + // both mutable and immutable PendingIntents. context.startIntentSender( pendingIntent.getIntentSender(), fillInIntent, - Intent.FLAG_ACTIVITY_NEW_TASK, - Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle()); + 0, 0, 0, opts.toBundle()); } catch (IntentSender.SendIntentException e) { android.util.Log.e(LOG_TAG, "Cannot send pending intent: ", e); return false; @@ -399,10 +401,15 @@ public class RemoteViews implements Parcelable, Filter { windowAnimationStyle.recycle(); if (enterAnimationId != 0) { - return ActivityOptions.makeCustomAnimation(context, enterAnimationId, 0); + final ActivityOptions opts = ActivityOptions.makeCustomAnimation(context, + enterAnimationId, 0); + opts.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + return opts; } } - return ActivityOptions.makeBasic(); + final ActivityOptions opts = ActivityOptions.makeBasic(); + opts.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + return opts; } } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index b9c6fa6020c4..2dcddff2f442 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -288,12 +288,19 @@ public final class PendingIntentRecord extends IIntentSender.Stub { resolvedType = key.requestResolvedType; } + // 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); + if (opts != null) { + finalIntent.addFlags(opts.getPendingIntentLaunchFlags()); + } + // Extract options before clearing calling identity mergedOptions = key.options; if (mergedOptions == null) { - mergedOptions = SafeActivityOptions.fromBundle(options); + mergedOptions = new SafeActivityOptions(opts); } else { - mergedOptions.setCallerOptions(ActivityOptions.fromBundle(options)); + mergedOptions.setCallerOptions(opts); } if (whitelistDuration != null) { |