Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 571ed8dc authored by Ashwini Oruganti's avatar Ashwini Oruganti
Browse files

Define FLAG_MUTABLE and add a compat change for explicit definition of...

Define FLAG_MUTABLE and add a compat change for explicit definition of PendingIntent mutability flags

For future releases, we will require that either FLAG_IMMUTABLE or
FLAG_MUTABLE is defined when a PendingIntent is created.

The check only results in a log.wtf for now while we notify, identify,
and update major PendingIntents. We will add a stricter
IllegalArgumentException soon.

- Define FLAG_MUTABLE
- Add a check and log.wtf that either FLAG_IMMUTABLE or FLAG_MUTABLE is
  specified on creation for future releases
- Update api/current.txt and non-updatable-api/current.txt to include
  FLAG_MUTABLE

Test: atest PendingIntentTest
Bug: 160794467
Change-Id: I1f1f72c6ce22358e98e9f38be2fb98b27e60898c
parent 38cc1531
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -6138,6 +6138,7 @@ package android.app {
    field @NonNull public static final android.os.Parcelable.Creator<android.app.PendingIntent> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.app.PendingIntent> CREATOR;
    field public static final int FLAG_CANCEL_CURRENT = 268435456; // 0x10000000
    field public static final int FLAG_CANCEL_CURRENT = 268435456; // 0x10000000
    field public static final int FLAG_IMMUTABLE = 67108864; // 0x4000000
    field public static final int FLAG_IMMUTABLE = 67108864; // 0x4000000
    field public static final int FLAG_MUTABLE = 33554432; // 0x2000000
    field public static final int FLAG_NO_CREATE = 536870912; // 0x20000000
    field public static final int FLAG_NO_CREATE = 536870912; // 0x20000000
    field public static final int FLAG_ONE_SHOT = 1073741824; // 0x40000000
    field public static final int FLAG_ONE_SHOT = 1073741824; // 0x40000000
    field public static final int FLAG_UPDATE_CURRENT = 134217728; // 0x8000000
    field public static final int FLAG_UPDATE_CURRENT = 134217728; // 0x8000000
+52 −0
Original line number Original line Diff line number Diff line
@@ -19,12 +19,16 @@ package android.app;
import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender;
import android.os.Build;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
@@ -35,6 +39,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.AndroidException;
import android.util.AndroidException;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import com.android.internal.os.IResultReceiver;
import com.android.internal.os.IResultReceiver;
@@ -102,11 +107,20 @@ import java.lang.annotation.RetentionPolicy;
 * FLAG_ONE_SHOT, <b>both</b> FLAG_ONE_SHOT and FLAG_NO_CREATE need to be supplied.
 * FLAG_ONE_SHOT, <b>both</b> FLAG_ONE_SHOT and FLAG_NO_CREATE need to be supplied.
 */
 */
public final class PendingIntent implements Parcelable {
public final class PendingIntent implements Parcelable {
    private static final String TAG = "PendingIntent";
    private final IIntentSender mTarget;
    private final IIntentSender mTarget;
    private IResultReceiver mCancelReceiver;
    private IResultReceiver mCancelReceiver;
    private IBinder mWhitelistToken;
    private IBinder mWhitelistToken;
    private ArraySet<CancelListener> mCancelListeners;
    private ArraySet<CancelListener> mCancelListeners;


    /**
     * It is now required to specify either {@link #FLAG_IMMUTABLE}
     * or {@link #FLAG_MUTABLE} when creating a PendingIntent.
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.R)
    static final long PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED = 160794467L;

    /** @hide */
    /** @hide */
    @IntDef(flag = true,
    @IntDef(flag = true,
            value = {
            value = {
@@ -115,6 +129,7 @@ public final class PendingIntent implements Parcelable {
                    FLAG_CANCEL_CURRENT,
                    FLAG_CANCEL_CURRENT,
                    FLAG_UPDATE_CURRENT,
                    FLAG_UPDATE_CURRENT,
                    FLAG_IMMUTABLE,
                    FLAG_IMMUTABLE,
                    FLAG_MUTABLE,


                    Intent.FILL_IN_ACTION,
                    Intent.FILL_IN_ACTION,
                    Intent.FILL_IN_DATA,
                    Intent.FILL_IN_DATA,
@@ -174,6 +189,20 @@ public final class PendingIntent implements Parcelable {
     */
     */
    public static final int FLAG_IMMUTABLE = 1<<26;
    public static final int FLAG_IMMUTABLE = 1<<26;


    /**
     * Flag indicating that the created PendingIntent should be mutable.
     * This flag cannot be combined with {@link #FLAG_IMMUTABLE}. <p>Up until
     * {@link android.os.Build.VERSION_CODES#R}, PendingIntents are assumed to
     * be mutable by default, unless {@link #FLAG_IMMUTABLE} is set. Starting
     * with {@link android.os.Build.VERSION_CODES#S}, it will be required to
     * explicitly specify the mutability of PendingIntents on creation with
     * either (@link #FLAG_IMMUTABLE} or {@link #FLAG_MUTABLE}. It is strongly
     * recommended to use {@link #FLAG_IMMUTABLE} when creating a
     * PendingIntent. {@link #FLAG_MUTABLE} should only be used when some
     * functionality relies on modifying the underlying intent.
     */
    public static final int FLAG_MUTABLE = 1<<25;

    /**
    /**
     * Exception thrown when trying to send through a PendingIntent that
     * Exception thrown when trying to send through a PendingIntent that
     * has been canceled or is otherwise no longer able to execute the request.
     * has been canceled or is otherwise no longer able to execute the request.
@@ -286,6 +315,23 @@ public final class PendingIntent implements Parcelable {
        sOnMarshaledListener.set(listener);
        sOnMarshaledListener.set(listener);
    }
    }


    private static void checkFlags(int flags, String packageName) {
        final boolean flagImmutableSet = (flags & PendingIntent.FLAG_IMMUTABLE) != 0;
        final boolean flagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0;

        if (flagImmutableSet && flagMutableSet) {
            throw new IllegalArgumentException(
                "Cannot set both FLAG_IMMUTABLE and FLAG_MUTABLE for PendingIntent");
        }

        if (Compatibility.isChangeEnabled(PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED)
                && !flagImmutableSet && !flagMutableSet) {
            Log.wtf(TAG, packageName + ": Targeting S+ (version " + Build.VERSION_CODES.S
                    + " and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE"
                    + " be specified when creating a PendingIntent");
        }
    }

    /**
    /**
     * Retrieve a PendingIntent that will start a new activity, like calling
     * Retrieve a PendingIntent that will start a new activity, like calling
     * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
     * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
@@ -350,6 +396,7 @@ public final class PendingIntent implements Parcelable {
        String packageName = context.getPackageName();
        String packageName = context.getPackageName();
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                context.getContentResolver()) : null;
                context.getContentResolver()) : null;
        checkFlags(flags, packageName);
        try {
        try {
            intent.migrateExtraStreamToClipData(context);
            intent.migrateExtraStreamToClipData(context);
            intent.prepareToLeaveProcess(context);
            intent.prepareToLeaveProcess(context);
@@ -376,6 +423,7 @@ public final class PendingIntent implements Parcelable {
        String packageName = context.getPackageName();
        String packageName = context.getPackageName();
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                context.getContentResolver()) : null;
                context.getContentResolver()) : null;
        checkFlags(flags, packageName);
        try {
        try {
            intent.migrateExtraStreamToClipData(context);
            intent.migrateExtraStreamToClipData(context);
            intent.prepareToLeaveProcess(context);
            intent.prepareToLeaveProcess(context);
@@ -495,6 +543,7 @@ public final class PendingIntent implements Parcelable {
            intents[i].prepareToLeaveProcess(context);
            intents[i].prepareToLeaveProcess(context);
            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
        }
        }
        checkFlags(flags, packageName);
        try {
        try {
            IIntentSender target =
            IIntentSender target =
                ActivityManager.getService().getIntentSenderWithFeature(
                ActivityManager.getService().getIntentSenderWithFeature(
@@ -521,6 +570,7 @@ public final class PendingIntent implements Parcelable {
            intents[i].prepareToLeaveProcess(context);
            intents[i].prepareToLeaveProcess(context);
            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
            resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
        }
        }
        checkFlags(flags, packageName);
        try {
        try {
            IIntentSender target =
            IIntentSender target =
                ActivityManager.getService().getIntentSenderWithFeature(
                ActivityManager.getService().getIntentSenderWithFeature(
@@ -572,6 +622,7 @@ public final class PendingIntent implements Parcelable {
        String packageName = context.getPackageName();
        String packageName = context.getPackageName();
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                context.getContentResolver()) : null;
                context.getContentResolver()) : null;
        checkFlags(flags, packageName);
        try {
        try {
            intent.prepareToLeaveProcess(context);
            intent.prepareToLeaveProcess(context);
            IIntentSender target =
            IIntentSender target =
@@ -651,6 +702,7 @@ public final class PendingIntent implements Parcelable {
        String packageName = context.getPackageName();
        String packageName = context.getPackageName();
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
        String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                context.getContentResolver()) : null;
                context.getContentResolver()) : null;
        checkFlags(flags, packageName);
        try {
        try {
            intent.prepareToLeaveProcess(context);
            intent.prepareToLeaveProcess(context);
            IIntentSender target =
            IIntentSender target =
+1 −0
Original line number Original line Diff line number Diff line
@@ -6138,6 +6138,7 @@ package android.app {
    field @NonNull public static final android.os.Parcelable.Creator<android.app.PendingIntent> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.app.PendingIntent> CREATOR;
    field public static final int FLAG_CANCEL_CURRENT = 268435456; // 0x10000000
    field public static final int FLAG_CANCEL_CURRENT = 268435456; // 0x10000000
    field public static final int FLAG_IMMUTABLE = 67108864; // 0x4000000
    field public static final int FLAG_IMMUTABLE = 67108864; // 0x4000000
    field public static final int FLAG_MUTABLE = 33554432; // 0x2000000
    field public static final int FLAG_NO_CREATE = 536870912; // 0x20000000
    field public static final int FLAG_NO_CREATE = 536870912; // 0x20000000
    field public static final int FLAG_ONE_SHOT = 1073741824; // 0x40000000
    field public static final int FLAG_ONE_SHOT = 1073741824; // 0x40000000
    field public static final int FLAG_UPDATE_CURRENT = 134217728; // 0x8000000
    field public static final int FLAG_UPDATE_CURRENT = 134217728; // 0x8000000