Loading core/java/android/app/BroadcastOptions.java +73 −81 Original line number Diff line number Diff line Loading @@ -49,21 +49,16 @@ import java.util.Objects; * Context.sendBroadcast(Intent)} and related methods. */ public class BroadcastOptions extends ComponentOptions { private @Flags int mFlags; private long mTemporaryAppAllowlistDuration; private @TempAllowListType int mTemporaryAppAllowlistType; private @ReasonCode int mTemporaryAppAllowlistReasonCode; private @Nullable String mTemporaryAppAllowlistReason; private int mMinManifestReceiverApiLevel = 0; private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; private boolean mDontSendToRestrictedApps = false; private boolean mAllowBackgroundActivityStarts; private String[] mRequireAllOfPermissions; private String[] mRequireNoneOfPermissions; private long mRequireCompatChangeId = CHANGE_INVALID; private boolean mRequireCompatChangeEnabled = true; private boolean mIsAlarmBroadcast = false; private boolean mIsDeferUntilActive = false; private boolean mShareIdentity = false; private long mIdForResponseEvent; private @Nullable IntentFilter mRemoveMatchingFilter; private @DeliveryGroupPolicy int mDeliveryGroupPolicy; Loading @@ -71,6 +66,25 @@ public class BroadcastOptions extends ComponentOptions { private @Nullable BundleMerger mDeliveryGroupExtrasMerger; private @Nullable IntentFilter mDeliveryGroupMatchingFilter; /** @hide */ @IntDef(flag = true, prefix = { "FLAG_" }, value = { FLAG_DONT_SEND_TO_RESTRICTED_APPS, FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS, FLAG_REQUIRE_COMPAT_CHANGE_ENABLED, FLAG_IS_ALARM_BROADCAST, FLAG_IS_DEFER_UNTIL_ACTIVE, FLAG_SHARE_IDENTITY, }) @Retention(RetentionPolicy.SOURCE) public @interface Flags {} private static final int FLAG_DONT_SEND_TO_RESTRICTED_APPS = 1 << 0; private static final int FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS = 1 << 1; private static final int FLAG_REQUIRE_COMPAT_CHANGE_ENABLED = 1 << 2; private static final int FLAG_IS_ALARM_BROADCAST = 1 << 3; private static final int FLAG_IS_DEFER_UNTIL_ACTIVE = 1 << 4; private static final int FLAG_SHARE_IDENTITY = 1 << 5; /** * Change ID which is invalid. * Loading Loading @@ -98,6 +112,11 @@ public class BroadcastOptions extends ComponentOptions { @Disabled public static final long CHANGE_ALWAYS_DISABLED = 210856463L; /** * Corresponds to {@link #mFlags}. */ private static final String KEY_FLAGS = "android:broadcast.flags"; /** * How long to temporarily put an app on the power allowlist when executing this broadcast * to it. Loading Loading @@ -126,18 +145,6 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL = "android:broadcast.maxManifestReceiverApiLevel"; /** * Corresponds to {@link #setDontSendToRestrictedApps}. */ private static final String KEY_DONT_SEND_TO_RESTRICTED_APPS = "android:broadcast.dontSendToRestrictedApps"; /** * Corresponds to {@link #setBackgroundActivityStartsAllowed}. */ private static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS = "android:broadcast.allowBackgroundActivityStarts"; /** * Corresponds to {@link #setRequireAllOfPermissions} * @hide Loading @@ -158,25 +165,6 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_REQUIRE_COMPAT_CHANGE_ID = "android:broadcast.requireCompatChangeId"; /** * Corresponds to {@link #setRequireCompatChange(long, boolean)} */ private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = "android:broadcast.requireCompatChangeEnabled"; /** * Corresponds to {@link #setAlarmBroadcast(boolean)} * @hide */ public static final String KEY_ALARM_BROADCAST = "android:broadcast.is_alarm"; /** * Whether the broadcasting app's identity should be available to the receiver. * @see #setShareIdentityEnabled(boolean) */ private static final String KEY_SHARE_IDENTITY = "android:broadcast.share_identity"; /** * @hide * @deprecated Use {@link android.os.PowerExemptionManager# Loading Loading @@ -207,12 +195,6 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_REMOVE_MATCHING_FILTER = "android:broadcast.removeMatchingFilter"; /** * Corresponds to {@link #setDeferUntilActive(boolean)}. */ private static final String KEY_DEFER_UNTIL_ACTIVE = "android:broadcast.deferuntilactive"; /** * Corresponds to {@link #setDeliveryGroupPolicy(int)}. */ Loading Loading @@ -308,6 +290,7 @@ public class BroadcastOptions extends ComponentOptions { public BroadcastOptions(@NonNull Bundle opts) { super(opts); // Match the logic in toBundle(). mFlags = opts.getInt(KEY_FLAGS, 0); if (opts.containsKey(KEY_TEMPORARY_APP_ALLOWLIST_DURATION)) { mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION); mTemporaryAppAllowlistType = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE); Loading @@ -320,16 +303,10 @@ public class BroadcastOptions extends ComponentOptions { mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0); mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, Build.VERSION_CODES.CUR_DEVELOPMENT); mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false); mAllowBackgroundActivityStarts = opts.getBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, false); mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS); mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); mIsAlarmBroadcast = opts.getBoolean(KEY_ALARM_BROADCAST, false); mShareIdentity = opts.getBoolean(KEY_SHARE_IDENTITY, false); mRemoveMatchingFilter = opts.getParcelable(KEY_REMOVE_MATCHING_FILTER, IntentFilter.class); mDeliveryGroupPolicy = opts.getInt(KEY_DELIVERY_GROUP_POLICY, Loading @@ -339,7 +316,6 @@ public class BroadcastOptions extends ComponentOptions { BundleMerger.class); mDeliveryGroupMatchingFilter = opts.getParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER, IntentFilter.class); mIsDeferUntilActive = opts.getBoolean(KEY_DEFER_UNTIL_ACTIVE, false); } /** Loading Loading @@ -521,7 +497,11 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public void setDontSendToRestrictedApps(boolean dontSendToRestrictedApps) { mDontSendToRestrictedApps = dontSendToRestrictedApps; if (dontSendToRestrictedApps) { mFlags |= FLAG_DONT_SEND_TO_RESTRICTED_APPS; } else { mFlags &= ~FLAG_DONT_SEND_TO_RESTRICTED_APPS; } } /** Loading @@ -529,7 +509,7 @@ public class BroadcastOptions extends ComponentOptions { * @return #setDontSendToRestrictedApps */ public boolean isDontSendToRestrictedApps() { return mDontSendToRestrictedApps; return (mFlags & FLAG_DONT_SEND_TO_RESTRICTED_APPS) != 0; } /** Loading @@ -540,15 +520,20 @@ public class BroadcastOptions extends ComponentOptions { @SystemApi @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean allowBackgroundActivityStarts) { mAllowBackgroundActivityStarts = allowBackgroundActivityStarts; if (allowBackgroundActivityStarts) { mFlags |= FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS; } else { mFlags &= ~FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS; } } /** * @hide * @return #setAllowBackgroundActivityStarts */ @Deprecated public boolean allowsBackgroundActivityStarts() { return mAllowBackgroundActivityStarts; return (mFlags & FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0; } /** Loading Loading @@ -610,7 +595,11 @@ public class BroadcastOptions extends ComponentOptions { @SystemApi public void setRequireCompatChange(long changeId, boolean enabled) { mRequireCompatChangeId = changeId; mRequireCompatChangeEnabled = enabled; if (enabled) { mFlags |= FLAG_REQUIRE_COMPAT_CHANGE_ENABLED; } else { mFlags &= ~FLAG_REQUIRE_COMPAT_CHANGE_ENABLED; } } /** Loading @@ -620,8 +609,7 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public void clearRequireCompatChange() { mRequireCompatChangeId = CHANGE_INVALID; mRequireCompatChangeEnabled = true; setRequireCompatChange(CHANGE_INVALID, true); } /** Loading @@ -633,7 +621,11 @@ public class BroadcastOptions extends ComponentOptions { * @param senderIsAlarm Whether the broadcast is alarm-triggered. */ public void setAlarmBroadcast(boolean senderIsAlarm) { mIsAlarmBroadcast = senderIsAlarm; if (senderIsAlarm) { mFlags |= FLAG_IS_ALARM_BROADCAST; } else { mFlags &= ~FLAG_IS_ALARM_BROADCAST; } } /** Loading @@ -642,7 +634,7 @@ public class BroadcastOptions extends ComponentOptions { * @hide */ public boolean isAlarmBroadcast() { return mIsAlarmBroadcast; return (mFlags & FLAG_IS_ALARM_BROADCAST) != 0; } /** Loading @@ -662,7 +654,11 @@ public class BroadcastOptions extends ComponentOptions { * @see BroadcastReceiver#getSentFromPackage() */ public @NonNull BroadcastOptions setShareIdentityEnabled(boolean shareIdentityEnabled) { mShareIdentity = shareIdentityEnabled; if (shareIdentityEnabled) { mFlags |= FLAG_SHARE_IDENTITY; } else { mFlags &= ~FLAG_SHARE_IDENTITY; } return this; } Loading @@ -675,7 +671,7 @@ public class BroadcastOptions extends ComponentOptions { * @see BroadcastReceiver#getSentFromPackage() */ public boolean isShareIdentityEnabled() { return mShareIdentity; return (mFlags & FLAG_SHARE_IDENTITY) != 0; } /** Loading Loading @@ -714,8 +710,8 @@ public class BroadcastOptions extends ComponentOptions { @TestApi public boolean testRequireCompatChange(int uid) { if (mRequireCompatChangeId != CHANGE_INVALID) { return CompatChanges.isChangeEnabled(mRequireCompatChangeId, uid) == mRequireCompatChangeEnabled; final boolean requireEnabled = (mFlags & FLAG_REQUIRE_COMPAT_CHANGE_ENABLED) != 0; return CompatChanges.isChangeEnabled(mRequireCompatChangeId, uid) == requireEnabled; } else { return true; } Loading Loading @@ -770,7 +766,11 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) { mIsDeferUntilActive = shouldDefer; if (shouldDefer) { mFlags |= FLAG_IS_DEFER_UNTIL_ACTIVE; } else { mFlags &= ~FLAG_IS_DEFER_UNTIL_ACTIVE; } return this; } Loading @@ -785,7 +785,7 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public boolean isDeferUntilActive() { return mIsDeferUntilActive; return (mFlags & FLAG_IS_DEFER_UNTIL_ACTIVE) != 0; } /** Loading Loading @@ -1057,30 +1057,21 @@ public class BroadcastOptions extends ComponentOptions { @Override public @NonNull Bundle toBundle() { Bundle b = super.toBundle(); if (mFlags != 0) { b.putInt(KEY_FLAGS, mFlags); } if (isTemporaryAppAllowlistSet()) { b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration); b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType); b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); } if (mIsAlarmBroadcast) { b.putBoolean(KEY_ALARM_BROADCAST, true); } if (mShareIdentity) { b.putBoolean(KEY_SHARE_IDENTITY, true); } if (mMinManifestReceiverApiLevel != 0) { b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); } if (mMaxManifestReceiverApiLevel != Build.VERSION_CODES.CUR_DEVELOPMENT) { b.putInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, mMaxManifestReceiverApiLevel); } if (mDontSendToRestrictedApps) { b.putBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, true); } if (mAllowBackgroundActivityStarts) { b.putBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, true); } if (mRequireAllOfPermissions != null) { b.putStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS, mRequireAllOfPermissions); } Loading @@ -1089,7 +1080,6 @@ public class BroadcastOptions extends ComponentOptions { } if (mRequireCompatChangeId != CHANGE_INVALID) { b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId); b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled); } if (mIdForResponseEvent != 0) { b.putLong(KEY_ID_FOR_RESPONSE_EVENT, mIdForResponseEvent); Loading @@ -1115,9 +1105,11 @@ public class BroadcastOptions extends ComponentOptions { if (mDeliveryGroupMatchingFilter != null) { b.putParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER, mDeliveryGroupMatchingFilter); } if (mIsDeferUntilActive) { b.putBoolean(KEY_DEFER_UNTIL_ACTIVE, mIsDeferUntilActive); } return b.isEmpty() ? null : b; } /** @hide */ public static @Nullable BroadcastOptions fromBundle(@Nullable Bundle options) { return (options != null) ? new BroadcastOptions(options) : null; } } core/java/android/app/ComponentOptions.java +6 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public class ComponentOptions { * Corresponds to {@link #setInteractive(boolean)} * @hide */ public static final String KEY_INTERACTIVE = "android:component.isInteractive"; private static final String KEY_INTERACTIVE = "android:component.isInteractive"; private @Nullable Boolean mPendingIntentBalAllowed = null; private boolean mPendingIntentBalAllowedByPermission = false; Loading Loading @@ -237,4 +237,9 @@ public class ComponentOptions { } return b; } /** @hide */ public static @Nullable ComponentOptions fromBundle(@Nullable Bundle options) { return (options != null) ? new ComponentOptions(options) : null; } } services/core/java/com/android/server/am/ActivityManagerService.java +17 −13 Original line number Diff line number Diff line Loading @@ -14228,9 +14228,15 @@ public class ActivityManagerService extends IActivityManager.Stub } // Apply permission policy around the use of specific broadcast options void enforceBroadcastOptionPermissionsInternal(@Nullable Bundle options, int callingUid) { void enforceBroadcastOptionPermissionsInternal( @Nullable Bundle options, int callingUid) { enforceBroadcastOptionPermissionsInternal(BroadcastOptions.fromBundle(options), callingUid); } void enforceBroadcastOptionPermissionsInternal( @Nullable BroadcastOptions options, int callingUid) { if (options != null && callingUid != Process.SYSTEM_UID) { if (options.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) { if (options.isAlarmBroadcast()) { if (DEBUG_BROADCAST_LIGHT) { Slog.w(TAG, "Non-system caller " + callingUid + " may not flag broadcast as alarm"); Loading @@ -14238,7 +14244,7 @@ public class ActivityManagerService extends IActivityManager.Stub throw new SecurityException( "Non-system callers may not flag broadcasts as alarm"); } if (options.containsKey(ComponentOptions.KEY_INTERACTIVE)) { if (options.isInteractive()) { enforceCallingPermission( android.Manifest.permission.COMPONENT_OPTION_INTERACTIVE, "setInteractive"); Loading Loading @@ -14276,10 +14282,10 @@ public class ActivityManagerService extends IActivityManager.Stub final int cookie = BroadcastQueue.traceBegin("broadcastIntentLockedTraced"); final int res = broadcastIntentLockedTraced(callerApp, callerPackage, callerFeatureId, intent, resolvedType, resultToApp, resultTo, resultCode, resultData, resultExtras, requiredPermissions, excludedPermissions, excludedPackages, appOp, bOptions, ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId, backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver); requiredPermissions, excludedPermissions, excludedPackages, appOp, BroadcastOptions.fromBundle(bOptions), ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId, backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver); BroadcastQueue.traceEnd(cookie); return res; } Loading @@ -14289,9 +14295,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Nullable String callerFeatureId, Intent intent, String resolvedType, ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions, String[] excludedPackages, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId, String[] excludedPermissions, String[] excludedPackages, int appOp, BroadcastOptions brOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId, BackgroundStartPrivileges backgroundStartPrivileges, @Nullable int[] broadcastAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) { Loading Loading @@ -14378,9 +14384,7 @@ public class ActivityManagerService extends IActivityManager.Stub } final String action = intent.getAction(); BroadcastOptions brOptions = null; if (bOptions != null) { brOptions = new BroadcastOptions(bOptions); if (brOptions != null) { if (brOptions.getTemporaryAppAllowlistDuration() > 0) { // See if the caller is allowed to do this. Note we are checking against // the actual real caller (not whoever provided the operation as say a services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -781,8 +781,8 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase { verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), onFinishedCaptor.capture(), any(Handler.class), isNull(), optionsCaptor.capture()); assertTrue(optionsCaptor.getValue() .getBoolean(BroadcastOptions.KEY_ALARM_BROADCAST, false)); final BroadcastOptions options = new BroadcastOptions(optionsCaptor.getValue()); assertTrue(options.isAlarmBroadcast()); } @Test Loading Loading
core/java/android/app/BroadcastOptions.java +73 −81 Original line number Diff line number Diff line Loading @@ -49,21 +49,16 @@ import java.util.Objects; * Context.sendBroadcast(Intent)} and related methods. */ public class BroadcastOptions extends ComponentOptions { private @Flags int mFlags; private long mTemporaryAppAllowlistDuration; private @TempAllowListType int mTemporaryAppAllowlistType; private @ReasonCode int mTemporaryAppAllowlistReasonCode; private @Nullable String mTemporaryAppAllowlistReason; private int mMinManifestReceiverApiLevel = 0; private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; private boolean mDontSendToRestrictedApps = false; private boolean mAllowBackgroundActivityStarts; private String[] mRequireAllOfPermissions; private String[] mRequireNoneOfPermissions; private long mRequireCompatChangeId = CHANGE_INVALID; private boolean mRequireCompatChangeEnabled = true; private boolean mIsAlarmBroadcast = false; private boolean mIsDeferUntilActive = false; private boolean mShareIdentity = false; private long mIdForResponseEvent; private @Nullable IntentFilter mRemoveMatchingFilter; private @DeliveryGroupPolicy int mDeliveryGroupPolicy; Loading @@ -71,6 +66,25 @@ public class BroadcastOptions extends ComponentOptions { private @Nullable BundleMerger mDeliveryGroupExtrasMerger; private @Nullable IntentFilter mDeliveryGroupMatchingFilter; /** @hide */ @IntDef(flag = true, prefix = { "FLAG_" }, value = { FLAG_DONT_SEND_TO_RESTRICTED_APPS, FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS, FLAG_REQUIRE_COMPAT_CHANGE_ENABLED, FLAG_IS_ALARM_BROADCAST, FLAG_IS_DEFER_UNTIL_ACTIVE, FLAG_SHARE_IDENTITY, }) @Retention(RetentionPolicy.SOURCE) public @interface Flags {} private static final int FLAG_DONT_SEND_TO_RESTRICTED_APPS = 1 << 0; private static final int FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS = 1 << 1; private static final int FLAG_REQUIRE_COMPAT_CHANGE_ENABLED = 1 << 2; private static final int FLAG_IS_ALARM_BROADCAST = 1 << 3; private static final int FLAG_IS_DEFER_UNTIL_ACTIVE = 1 << 4; private static final int FLAG_SHARE_IDENTITY = 1 << 5; /** * Change ID which is invalid. * Loading Loading @@ -98,6 +112,11 @@ public class BroadcastOptions extends ComponentOptions { @Disabled public static final long CHANGE_ALWAYS_DISABLED = 210856463L; /** * Corresponds to {@link #mFlags}. */ private static final String KEY_FLAGS = "android:broadcast.flags"; /** * How long to temporarily put an app on the power allowlist when executing this broadcast * to it. Loading Loading @@ -126,18 +145,6 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL = "android:broadcast.maxManifestReceiverApiLevel"; /** * Corresponds to {@link #setDontSendToRestrictedApps}. */ private static final String KEY_DONT_SEND_TO_RESTRICTED_APPS = "android:broadcast.dontSendToRestrictedApps"; /** * Corresponds to {@link #setBackgroundActivityStartsAllowed}. */ private static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS = "android:broadcast.allowBackgroundActivityStarts"; /** * Corresponds to {@link #setRequireAllOfPermissions} * @hide Loading @@ -158,25 +165,6 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_REQUIRE_COMPAT_CHANGE_ID = "android:broadcast.requireCompatChangeId"; /** * Corresponds to {@link #setRequireCompatChange(long, boolean)} */ private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = "android:broadcast.requireCompatChangeEnabled"; /** * Corresponds to {@link #setAlarmBroadcast(boolean)} * @hide */ public static final String KEY_ALARM_BROADCAST = "android:broadcast.is_alarm"; /** * Whether the broadcasting app's identity should be available to the receiver. * @see #setShareIdentityEnabled(boolean) */ private static final String KEY_SHARE_IDENTITY = "android:broadcast.share_identity"; /** * @hide * @deprecated Use {@link android.os.PowerExemptionManager# Loading Loading @@ -207,12 +195,6 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_REMOVE_MATCHING_FILTER = "android:broadcast.removeMatchingFilter"; /** * Corresponds to {@link #setDeferUntilActive(boolean)}. */ private static final String KEY_DEFER_UNTIL_ACTIVE = "android:broadcast.deferuntilactive"; /** * Corresponds to {@link #setDeliveryGroupPolicy(int)}. */ Loading Loading @@ -308,6 +290,7 @@ public class BroadcastOptions extends ComponentOptions { public BroadcastOptions(@NonNull Bundle opts) { super(opts); // Match the logic in toBundle(). mFlags = opts.getInt(KEY_FLAGS, 0); if (opts.containsKey(KEY_TEMPORARY_APP_ALLOWLIST_DURATION)) { mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION); mTemporaryAppAllowlistType = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE); Loading @@ -320,16 +303,10 @@ public class BroadcastOptions extends ComponentOptions { mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0); mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, Build.VERSION_CODES.CUR_DEVELOPMENT); mDontSendToRestrictedApps = opts.getBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, false); mAllowBackgroundActivityStarts = opts.getBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, false); mRequireAllOfPermissions = opts.getStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS); mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); mIsAlarmBroadcast = opts.getBoolean(KEY_ALARM_BROADCAST, false); mShareIdentity = opts.getBoolean(KEY_SHARE_IDENTITY, false); mRemoveMatchingFilter = opts.getParcelable(KEY_REMOVE_MATCHING_FILTER, IntentFilter.class); mDeliveryGroupPolicy = opts.getInt(KEY_DELIVERY_GROUP_POLICY, Loading @@ -339,7 +316,6 @@ public class BroadcastOptions extends ComponentOptions { BundleMerger.class); mDeliveryGroupMatchingFilter = opts.getParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER, IntentFilter.class); mIsDeferUntilActive = opts.getBoolean(KEY_DEFER_UNTIL_ACTIVE, false); } /** Loading Loading @@ -521,7 +497,11 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public void setDontSendToRestrictedApps(boolean dontSendToRestrictedApps) { mDontSendToRestrictedApps = dontSendToRestrictedApps; if (dontSendToRestrictedApps) { mFlags |= FLAG_DONT_SEND_TO_RESTRICTED_APPS; } else { mFlags &= ~FLAG_DONT_SEND_TO_RESTRICTED_APPS; } } /** Loading @@ -529,7 +509,7 @@ public class BroadcastOptions extends ComponentOptions { * @return #setDontSendToRestrictedApps */ public boolean isDontSendToRestrictedApps() { return mDontSendToRestrictedApps; return (mFlags & FLAG_DONT_SEND_TO_RESTRICTED_APPS) != 0; } /** Loading @@ -540,15 +520,20 @@ public class BroadcastOptions extends ComponentOptions { @SystemApi @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean allowBackgroundActivityStarts) { mAllowBackgroundActivityStarts = allowBackgroundActivityStarts; if (allowBackgroundActivityStarts) { mFlags |= FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS; } else { mFlags &= ~FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS; } } /** * @hide * @return #setAllowBackgroundActivityStarts */ @Deprecated public boolean allowsBackgroundActivityStarts() { return mAllowBackgroundActivityStarts; return (mFlags & FLAG_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0; } /** Loading Loading @@ -610,7 +595,11 @@ public class BroadcastOptions extends ComponentOptions { @SystemApi public void setRequireCompatChange(long changeId, boolean enabled) { mRequireCompatChangeId = changeId; mRequireCompatChangeEnabled = enabled; if (enabled) { mFlags |= FLAG_REQUIRE_COMPAT_CHANGE_ENABLED; } else { mFlags &= ~FLAG_REQUIRE_COMPAT_CHANGE_ENABLED; } } /** Loading @@ -620,8 +609,7 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public void clearRequireCompatChange() { mRequireCompatChangeId = CHANGE_INVALID; mRequireCompatChangeEnabled = true; setRequireCompatChange(CHANGE_INVALID, true); } /** Loading @@ -633,7 +621,11 @@ public class BroadcastOptions extends ComponentOptions { * @param senderIsAlarm Whether the broadcast is alarm-triggered. */ public void setAlarmBroadcast(boolean senderIsAlarm) { mIsAlarmBroadcast = senderIsAlarm; if (senderIsAlarm) { mFlags |= FLAG_IS_ALARM_BROADCAST; } else { mFlags &= ~FLAG_IS_ALARM_BROADCAST; } } /** Loading @@ -642,7 +634,7 @@ public class BroadcastOptions extends ComponentOptions { * @hide */ public boolean isAlarmBroadcast() { return mIsAlarmBroadcast; return (mFlags & FLAG_IS_ALARM_BROADCAST) != 0; } /** Loading @@ -662,7 +654,11 @@ public class BroadcastOptions extends ComponentOptions { * @see BroadcastReceiver#getSentFromPackage() */ public @NonNull BroadcastOptions setShareIdentityEnabled(boolean shareIdentityEnabled) { mShareIdentity = shareIdentityEnabled; if (shareIdentityEnabled) { mFlags |= FLAG_SHARE_IDENTITY; } else { mFlags &= ~FLAG_SHARE_IDENTITY; } return this; } Loading @@ -675,7 +671,7 @@ public class BroadcastOptions extends ComponentOptions { * @see BroadcastReceiver#getSentFromPackage() */ public boolean isShareIdentityEnabled() { return mShareIdentity; return (mFlags & FLAG_SHARE_IDENTITY) != 0; } /** Loading Loading @@ -714,8 +710,8 @@ public class BroadcastOptions extends ComponentOptions { @TestApi public boolean testRequireCompatChange(int uid) { if (mRequireCompatChangeId != CHANGE_INVALID) { return CompatChanges.isChangeEnabled(mRequireCompatChangeId, uid) == mRequireCompatChangeEnabled; final boolean requireEnabled = (mFlags & FLAG_REQUIRE_COMPAT_CHANGE_ENABLED) != 0; return CompatChanges.isChangeEnabled(mRequireCompatChangeId, uid) == requireEnabled; } else { return true; } Loading Loading @@ -770,7 +766,11 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) { mIsDeferUntilActive = shouldDefer; if (shouldDefer) { mFlags |= FLAG_IS_DEFER_UNTIL_ACTIVE; } else { mFlags &= ~FLAG_IS_DEFER_UNTIL_ACTIVE; } return this; } Loading @@ -785,7 +785,7 @@ public class BroadcastOptions extends ComponentOptions { */ @SystemApi public boolean isDeferUntilActive() { return mIsDeferUntilActive; return (mFlags & FLAG_IS_DEFER_UNTIL_ACTIVE) != 0; } /** Loading Loading @@ -1057,30 +1057,21 @@ public class BroadcastOptions extends ComponentOptions { @Override public @NonNull Bundle toBundle() { Bundle b = super.toBundle(); if (mFlags != 0) { b.putInt(KEY_FLAGS, mFlags); } if (isTemporaryAppAllowlistSet()) { b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration); b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType); b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); } if (mIsAlarmBroadcast) { b.putBoolean(KEY_ALARM_BROADCAST, true); } if (mShareIdentity) { b.putBoolean(KEY_SHARE_IDENTITY, true); } if (mMinManifestReceiverApiLevel != 0) { b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); } if (mMaxManifestReceiverApiLevel != Build.VERSION_CODES.CUR_DEVELOPMENT) { b.putInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, mMaxManifestReceiverApiLevel); } if (mDontSendToRestrictedApps) { b.putBoolean(KEY_DONT_SEND_TO_RESTRICTED_APPS, true); } if (mAllowBackgroundActivityStarts) { b.putBoolean(KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS, true); } if (mRequireAllOfPermissions != null) { b.putStringArray(KEY_REQUIRE_ALL_OF_PERMISSIONS, mRequireAllOfPermissions); } Loading @@ -1089,7 +1080,6 @@ public class BroadcastOptions extends ComponentOptions { } if (mRequireCompatChangeId != CHANGE_INVALID) { b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId); b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled); } if (mIdForResponseEvent != 0) { b.putLong(KEY_ID_FOR_RESPONSE_EVENT, mIdForResponseEvent); Loading @@ -1115,9 +1105,11 @@ public class BroadcastOptions extends ComponentOptions { if (mDeliveryGroupMatchingFilter != null) { b.putParcelable(KEY_DELIVERY_GROUP_MATCHING_FILTER, mDeliveryGroupMatchingFilter); } if (mIsDeferUntilActive) { b.putBoolean(KEY_DEFER_UNTIL_ACTIVE, mIsDeferUntilActive); } return b.isEmpty() ? null : b; } /** @hide */ public static @Nullable BroadcastOptions fromBundle(@Nullable Bundle options) { return (options != null) ? new BroadcastOptions(options) : null; } }
core/java/android/app/ComponentOptions.java +6 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public class ComponentOptions { * Corresponds to {@link #setInteractive(boolean)} * @hide */ public static final String KEY_INTERACTIVE = "android:component.isInteractive"; private static final String KEY_INTERACTIVE = "android:component.isInteractive"; private @Nullable Boolean mPendingIntentBalAllowed = null; private boolean mPendingIntentBalAllowedByPermission = false; Loading Loading @@ -237,4 +237,9 @@ public class ComponentOptions { } return b; } /** @hide */ public static @Nullable ComponentOptions fromBundle(@Nullable Bundle options) { return (options != null) ? new ComponentOptions(options) : null; } }
services/core/java/com/android/server/am/ActivityManagerService.java +17 −13 Original line number Diff line number Diff line Loading @@ -14228,9 +14228,15 @@ public class ActivityManagerService extends IActivityManager.Stub } // Apply permission policy around the use of specific broadcast options void enforceBroadcastOptionPermissionsInternal(@Nullable Bundle options, int callingUid) { void enforceBroadcastOptionPermissionsInternal( @Nullable Bundle options, int callingUid) { enforceBroadcastOptionPermissionsInternal(BroadcastOptions.fromBundle(options), callingUid); } void enforceBroadcastOptionPermissionsInternal( @Nullable BroadcastOptions options, int callingUid) { if (options != null && callingUid != Process.SYSTEM_UID) { if (options.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) { if (options.isAlarmBroadcast()) { if (DEBUG_BROADCAST_LIGHT) { Slog.w(TAG, "Non-system caller " + callingUid + " may not flag broadcast as alarm"); Loading @@ -14238,7 +14244,7 @@ public class ActivityManagerService extends IActivityManager.Stub throw new SecurityException( "Non-system callers may not flag broadcasts as alarm"); } if (options.containsKey(ComponentOptions.KEY_INTERACTIVE)) { if (options.isInteractive()) { enforceCallingPermission( android.Manifest.permission.COMPONENT_OPTION_INTERACTIVE, "setInteractive"); Loading Loading @@ -14276,10 +14282,10 @@ public class ActivityManagerService extends IActivityManager.Stub final int cookie = BroadcastQueue.traceBegin("broadcastIntentLockedTraced"); final int res = broadcastIntentLockedTraced(callerApp, callerPackage, callerFeatureId, intent, resolvedType, resultToApp, resultTo, resultCode, resultData, resultExtras, requiredPermissions, excludedPermissions, excludedPackages, appOp, bOptions, ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId, backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver); requiredPermissions, excludedPermissions, excludedPackages, appOp, BroadcastOptions.fromBundle(bOptions), ordered, sticky, callingPid, callingUid, realCallingUid, realCallingPid, userId, backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver); BroadcastQueue.traceEnd(cookie); return res; } Loading @@ -14289,9 +14295,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Nullable String callerFeatureId, Intent intent, String resolvedType, ProcessRecord resultToApp, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions, String[] excludedPackages, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId, String[] excludedPermissions, String[] excludedPackages, int appOp, BroadcastOptions brOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId, BackgroundStartPrivileges backgroundStartPrivileges, @Nullable int[] broadcastAllowList, @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) { Loading Loading @@ -14378,9 +14384,7 @@ public class ActivityManagerService extends IActivityManager.Stub } final String action = intent.getAction(); BroadcastOptions brOptions = null; if (bOptions != null) { brOptions = new BroadcastOptions(bOptions); if (brOptions != null) { if (brOptions.getTemporaryAppAllowlistDuration() > 0) { // See if the caller is allowed to do this. Note we are checking against // the actual real caller (not whoever provided the operation as say a
services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +2 −2 Original line number Diff line number Diff line Loading @@ -781,8 +781,8 @@ public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase { verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), onFinishedCaptor.capture(), any(Handler.class), isNull(), optionsCaptor.capture()); assertTrue(optionsCaptor.getValue() .getBoolean(BroadcastOptions.KEY_ALARM_BROADCAST, false)); final BroadcastOptions options = new BroadcastOptions(optionsCaptor.getValue()); assertTrue(options.isAlarmBroadcast()); } @Test Loading