diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index deb81918e940d..20a93fdc9abc2 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -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 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); diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 175da9cab77be..81a8680cdbf0f 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -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 diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 16d8d153a574a..a50746d4c30c3 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -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) {