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
This commit is contained in:
Ricky Wai
2021-09-27 14:24:24 +00:00
parent 9706479634
commit f4cedb2773
3 changed files with 35 additions and 30 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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) {