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

Commit 6c0a479e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Synthesize app PendingIntents rather than wrap them" into sc-dev

parents c1b024d2 e9030d39
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -560,6 +560,14 @@ public abstract class ActivityManagerInternal {
    @Nullable
    public abstract Intent getIntentForIntentSender(IIntentSender sender);

    /**
     * Effectively PendingIntent.getActivityForUser(), but the PendingIntent is
     * owned by the given uid rather than by the caller (i.e. the system).
     */
    public abstract PendingIntent getPendingIntentActivityAsApp(
            int requestCode, @NonNull Intent intent, int flags, Bundle options,
            String ownerPkgName, int ownerUid);

    /**
     * @return mBootTimeTempAllowlistDuration of ActivityManagerConstants.
     */
+6 −6
Original line number Diff line number Diff line
@@ -358,12 +358,6 @@ public final class PendingIntent implements Parcelable {
    private static void checkFlags(int flags, String packageName) {
        final boolean flagImmutableSet = (flags & PendingIntent.FLAG_IMMUTABLE) != 0;
        final boolean flagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0;
        String msg = 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.\nStrongly consider"
                    + " using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality"
                    + " depends on the PendingIntent being mutable, e.g. if it needs to"
                    + " be used with inline replies or bubbles.";

        if (flagImmutableSet && flagMutableSet) {
            throw new IllegalArgumentException(
@@ -372,6 +366,12 @@ public final class PendingIntent implements Parcelable {

        if (Compatibility.isChangeEnabled(PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED)
                && !flagImmutableSet && !flagMutableSet) {
            String msg = 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.\nStrongly consider"
                    + " using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality"
                    + " depends on the PendingIntent being mutable, e.g. if it needs to"
                    + " be used with inline replies or bubbles.";
                throw new IllegalArgumentException(msg);
        }
    }
+55 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_ISOLATED_STORAGE;
import static android.app.ActivityManager.INSTR_FLAG_DISABLE_TEST_API_CHECKS;
import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART;
import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -4815,10 +4816,27 @@ public class ActivityManagerService extends IActivityManager.Stub
    public IIntentSender getIntentSenderWithFeature(int type, String packageName, String featureId,
            IBinder token, String resultWho, int requestCode, Intent[] intents,
            String[] resolvedTypes, int flags, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("getIntentSender");
        return getIntentSenderWithFeatureAsApp(type, packageName, featureId, token, resultWho,
                requestCode, intents, resolvedTypes, flags, bOptions, userId,
                Binder.getCallingUid());
    }
    /**
     * System-internal callers can invoke this with owningUid being the app's own identity
     * rather than the public API's behavior of always assigning ownership to the actual
     * caller identity.  This will create an IntentSender as though the package/userid/uid app
     * were the caller, so that the ultimate PendingIntent is triggered with only the app's
     * capabilities and not the system's.  Used in cases like notification groups where
     * the OS must synthesize a PendingIntent on an app's behalf.
     */
    public IIntentSender getIntentSenderWithFeatureAsApp(int type, String packageName,
            String featureId, IBinder token, String resultWho, int requestCode, Intent[] intents,
            String[] resolvedTypes, int flags, Bundle bOptions, int userId, int owningUid) {
        // NOTE: The service lock isn't held in this method because nothing in the method requires
        // the service lock to be held.
        enforceNotIsolatedCaller("getIntentSender");
        // Refuse possible leaked file descriptors
        if (intents != null) {
            if (intents.length < 1) {
@@ -4849,9 +4867,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        int callingUid = Binder.getCallingUid();
        int origUserId = userId;
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), owningUid, userId,
                type == ActivityManager.INTENT_SENDER_BROADCAST,
                ALLOW_NON_FULL, "getIntentSender", null);
        if (origUserId == UserHandle.USER_CURRENT) {
@@ -4861,13 +4878,13 @@ public class ActivityManagerService extends IActivityManager.Stub
            userId = UserHandle.USER_CURRENT;
        }
        try {
            if (callingUid != 0 && callingUid != SYSTEM_UID) {
            if (owningUid != 0 && owningUid != SYSTEM_UID) {
                final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
                if (!UserHandle.isSameApp(callingUid, uid)) {
                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(owningUid));
                if (!UserHandle.isSameApp(owningUid, uid)) {
                    String msg = "Permission Denial: getIntentSender() from pid="
                            + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                            + ", uid=" + owningUid
                            + ", (need uid=" + uid + ")"
                            + " is not allowed to send as package " + packageName;
                    Slog.w(TAG, msg);
@@ -4876,12 +4893,12 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
                return mAtmInternal.getIntentSender(type, packageName, featureId, callingUid,
                return mAtmInternal.getIntentSender(type, packageName, featureId, owningUid,
                        userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
                        bOptions);
            }
            return mPendingIntentController.getIntentSender(type, packageName, featureId,
                    callingUid, userId, token, resultWho, requestCode, intents, resolvedTypes,
                    owningUid, userId, token, resultWho, requestCode, intents, resolvedTypes,
                    flags, bOptions);
        } catch (RemoteException e) {
            throw new SecurityException(e);
@@ -16058,6 +16075,32 @@ public class ActivityManagerService extends IActivityManager.Stub
            return ActivityManagerService.this.getIntentForIntentSender(sender);
        }
        @Override
        public PendingIntent getPendingIntentActivityAsApp(
                int requestCode, @NonNull Intent intent, int flags, Bundle options,
                String ownerPkg, int ownerUid) {
            // system callers must explicitly set mutability state
            final boolean flagImmutableSet = (flags & PendingIntent.FLAG_IMMUTABLE) != 0;
            final boolean flagMutableSet = (flags & PendingIntent.FLAG_MUTABLE) != 0;
            if (flagImmutableSet == flagMutableSet) {
                throw new IllegalArgumentException(
                        "Must set exactly one of FLAG_IMMUTABLE or FLAG_MUTABLE");
            }
            final Context context = ActivityManagerService.this.mContext;
            String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
            intent.migrateExtraStreamToClipData(context);
            intent.prepareToLeaveProcess(context);
            IIntentSender target =
                    ActivityManagerService.this.getIntentSenderWithFeatureAsApp(
                            INTENT_SENDER_ACTIVITY, ownerPkg,
                            context.getAttributionTag(), null, null, requestCode,
                            new Intent[] { intent },
                            resolvedType != null ? new String[] { resolvedType } : null,
                            flags, options, UserHandle.getUserId(ownerUid), ownerUid);
            return target != null ? new PendingIntent(target) : null;
        }
        @Override
        public long getBootTimeTempAllowListDuration() {
            // Do not lock ActivityManagerService.this here, this API is called by
+5 −3
Original line number Diff line number Diff line
@@ -5677,9 +5677,11 @@ public class NotificationManagerService extends SystemService {
                summaryNotification.extras.putAll(extras);
                Intent appIntent = getContext().getPackageManager().getLaunchIntentForPackage(pkg);
                if (appIntent != null) {
                    summaryNotification.contentIntent = PendingIntent.getActivityAsUser(
                            getContext(), 0, appIntent, PendingIntent.FLAG_IMMUTABLE, null,
                            UserHandle.of(userId));
                    final ActivityManagerInternal ami = LocalServices
                            .getService(ActivityManagerInternal.class);
                    summaryNotification.contentIntent = ami.getPendingIntentActivityAsApp(
                            0, appIntent, PendingIntent.FLAG_IMMUTABLE, null,
                            pkg, appInfo.uid);
                }
                final StatusBarNotification summarySbn =
                        new StatusBarNotification(adjustedSbn.getPackageName(),