summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityOptions.java28
-rw-r--r--core/java/android/widget/RemoteViews.java15
-rw-r--r--services/core/java/com/android/server/am/PendingIntentRecord.java11
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) {