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

Commit f4cedb27 authored by Ricky Wai's avatar Ricky Wai
Browse files

Add PendingIntent BroadcastOptions BAL API implementation

Now PendingIntent sender can use API to allow/block trampoline activity started
by broadcast created by PendingIntent creator.

Bug: 192341120
Test: atest BackgroundActivityLaunchTest
Change-Id: I4952e05f5d086483c5b3d3e1c16eb7a69e7141d0
parent 97064796
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -326,6 +326,7 @@ public class AlarmManagerService extends SystemService {
    BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic();
    BroadcastOptions mOptsTimeBroadcast = BroadcastOptions.makeBasic();
    ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic();
    BroadcastOptions mBroadcastOptsRestrictBal = BroadcastOptions.makeBasic();

    // TODO(b/172085676): Move inside alarm store.
    private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
@@ -1700,6 +1701,7 @@ public class AlarmManagerService extends SystemService {
        mOptsWithoutFgs.setPendingIntentBackgroundActivityLaunchAllowed(false);
        mOptsTimeBroadcast.setPendingIntentBackgroundActivityLaunchAllowed(false);
        mActivityOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false);
        mBroadcastOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false);
        mMetricsHelper = new MetricsHelper(getContext(), mLock);

        mListenerDeathRecipient = new IBinder.DeathRecipient() {
@@ -4560,6 +4562,18 @@ public class AlarmManagerService extends SystemService {
        return canAffordBillLocked(alarm, TareBill.getAppropriateBill(alarm));
    }

    private Bundle getAlarmOperationBundle(Alarm alarm) {
        if (alarm.mIdleOptions != null) {
            return alarm.mIdleOptions;
        } else {
            if (alarm.operation.isActivity()) {
                return mActivityOptsRestrictBal.toBundle();
            } else {
                return mBroadcastOptsRestrictBal.toBundle();
            }
        }
    }

    @VisibleForTesting
    class AlarmHandler extends Handler {
        public static final int ALARM_EVENT = 1;
@@ -4599,12 +4613,7 @@ public class AlarmManagerService extends SystemService {
                        Alarm alarm = triggerList.get(i);
                        try {
                            // Disallow AlarmManager to start random background activity.
                            final Bundle bundle;
                            if (alarm.operation.isActivity()) {
                                bundle = mActivityOptsRestrictBal.toBundle();
                            } else {
                                bundle = null;
                            }
                            final Bundle bundle = getAlarmOperationBundle(alarm);
                            alarm.operation.send(/* context */ null, /* code */0, /* intent */
                                    null, /* onFinished */null, /* handler */
                                    null, /* requiredPermission */ null, bundle);
@@ -5208,16 +5217,7 @@ public class AlarmManagerService extends SystemService {
                    mSendCount++;

                    try {
                        final Bundle bundle;
                        if (alarm.mIdleOptions != null) {
                            bundle = alarm.mIdleOptions;
                        } else {
                            if (alarm.operation.isActivity()) {
                                bundle = mActivityOptsRestrictBal.toBundle();
                            } else {
                                bundle = null;
                            }
                        }
                        final Bundle bundle = getAlarmOperationBundle(alarm);
                        alarm.operation.send(getContext(), 0,
                                mBackgroundIntent.putExtra(Intent.EXTRA_ALARM_COUNT, alarm.count),
                                mDeliveryTracker, mHandler, null, bundle);
+18 −1
Original line number Diff line number Diff line
@@ -310,6 +310,22 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
                requiredPermission, null, null, 0, 0, 0, options);
    }

    public static boolean isPendingIntentBalAllowedByCaller(
            @Nullable ActivityOptions activityOptions) {
        if (activityOptions == null) {
            return ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
        }
        return isPendingIntentBalAllowedByCaller(activityOptions.toBundle());
    }

    private static boolean isPendingIntentBalAllowedByCaller(@Nullable Bundle options) {
        if (options == null) {
            return ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
        }
        return options.getBoolean(ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
                ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT);
    }

    public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken,
            IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo,
            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) {
@@ -431,7 +447,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
            // temporarily allow receivers and services to open activities from background if the
            // PendingIntent.send() caller was foreground at the time of sendInner() call
            final boolean allowTrampoline = uid != callingUid
                    && controller.mAtmInternal.isUidForeground(callingUid);
                    && controller.mAtmInternal.isUidForeground(callingUid)
                    && isPendingIntentBalAllowedByCaller(options);

            // note: we on purpose don't pass in the information about the PendingIntent's creator,
            // like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because
+1 −13
Original line number Diff line number Diff line
@@ -1254,18 +1254,6 @@ class ActivityStarter {
        return activity != null && packageName.equals(activity.getPackageName());
    }

    private static boolean isPendingIntentBalAllowedByCaller(ActivityOptions activityOptions) {
        if (activityOptions == null) {
            return ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
        }
        final Bundle options = activityOptions.toBundle();
        if (options == null) {
            return ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
        }
        return options.getBoolean(ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
                ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT);
    }

    boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
            final String callingPackage, int realCallingUid, int realCallingPid,
            WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
@@ -1345,7 +1333,7 @@ class ActivityStarter {

        // Legacy behavior allows to use caller foreground state to bypass BAL restriction.
        final boolean balAllowedByPiSender =
                isPendingIntentBalAllowedByCaller(checkedOptions);
                PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions);

        if (balAllowedByPiSender && realCallingUid != callingUid) {
            if (isPiBalOptionEnabled) {