Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +11 −5 Original line number Original line Diff line number Diff line Loading @@ -335,12 +335,18 @@ public class AlarmManagerService extends SystemService { "REORDER_ALARMS_FOR_TARE", "REORDER_ALARMS_FOR_TARE", }); }); BroadcastOptions mOptsWithFgs = BroadcastOptions.makeBasic(); BroadcastOptions mOptsWithFgs = makeBasicAlarmBroadcastOptions(); BroadcastOptions mOptsWithFgsForAlarmClock = BroadcastOptions.makeBasic(); BroadcastOptions mOptsWithFgsForAlarmClock = makeBasicAlarmBroadcastOptions(); BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic(); BroadcastOptions mOptsWithoutFgs = makeBasicAlarmBroadcastOptions(); BroadcastOptions mOptsTimeBroadcast = BroadcastOptions.makeBasic(); BroadcastOptions mOptsTimeBroadcast = makeBasicAlarmBroadcastOptions(); ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic(); ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic(); BroadcastOptions mBroadcastOptsRestrictBal = BroadcastOptions.makeBasic(); BroadcastOptions mBroadcastOptsRestrictBal = makeBasicAlarmBroadcastOptions(); private static BroadcastOptions makeBasicAlarmBroadcastOptions() { final BroadcastOptions b = BroadcastOptions.makeBasic(); b.setAlarmBroadcast(true); return b; } // TODO(b/172085676): Move inside alarm store. // TODO(b/172085676): Move inside alarm store. private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = Loading core/java/android/app/BroadcastOptions.java +33 −0 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,7 @@ public class BroadcastOptions extends ComponentOptions { private String[] mRequireNoneOfPermissions; private String[] mRequireNoneOfPermissions; private long mRequireCompatChangeId = CHANGE_INVALID; private long mRequireCompatChangeId = CHANGE_INVALID; private boolean mRequireCompatChangeEnabled = true; private boolean mRequireCompatChangeEnabled = true; private boolean mIsAlarmBroadcast = false; private long mIdForResponseEvent; private long mIdForResponseEvent; /** /** Loading Loading @@ -148,6 +149,13 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = "android:broadcast.requireCompatChangeEnabled"; "android:broadcast.requireCompatChangeEnabled"; /** * Corresponds to {@link #setAlarmBroadcast(boolean)} * @hide */ public static final String KEY_ALARM_BROADCAST = "android:broadcast.is_alarm"; /** /** * @hide * @hide * @deprecated Use {@link android.os.PowerExemptionManager# * @deprecated Use {@link android.os.PowerExemptionManager# Loading Loading @@ -207,6 +215,7 @@ public class BroadcastOptions extends ComponentOptions { mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); mIsAlarmBroadcast = opts.getBoolean(KEY_ALARM_BROADCAST, false); } } /** /** Loading Loading @@ -498,6 +507,27 @@ public class BroadcastOptions extends ComponentOptions { mRequireCompatChangeEnabled = true; mRequireCompatChangeEnabled = true; } } /** * When set, this broadcast will be understood as having originated from an * alarm going off. Only the OS itself can use this option; uses by other * senders will be ignored. * @hide * * @param senderIsAlarm Whether the broadcast is alarm-triggered. */ public void setAlarmBroadcast(boolean senderIsAlarm) { mIsAlarmBroadcast = senderIsAlarm; } /** * Did this broadcast originate from an alarm triggering? * @return true if this broadcast is an alarm message, false otherwise * @hide */ public boolean isAlarmBroadcast() { return mIsAlarmBroadcast; } /** {@hide} */ /** {@hide} */ public long getRequireCompatChangeId() { public long getRequireCompatChangeId() { return mRequireCompatChangeId; return mRequireCompatChangeId; Loading Loading @@ -560,6 +590,9 @@ public class BroadcastOptions extends ComponentOptions { b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); } } if (mIsAlarmBroadcast) { b.putBoolean(KEY_ALARM_BROADCAST, true); } if (mMinManifestReceiverApiLevel != 0) { if (mMinManifestReceiverApiLevel != 0) { b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); } } Loading services/core/java/com/android/server/am/ActivityManagerService.java +14 −0 Original line number Original line Diff line number Diff line Loading @@ -14445,6 +14445,19 @@ public class ActivityManagerService extends IActivityManager.Stub final int callingPid = Binder.getCallingPid(); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); // Non-system callers can't declare that a broadcast is alarm-related. // The PendingIntent invocation case is handled in PendingIntentRecord. if (bOptions != null && callingUid != SYSTEM_UID) { if (bOptions.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) { if (DEBUG_BROADCAST) { Slog.w(TAG, "Non-system caller " + callingUid + " may not flag broadcast as alarm-related"); } throw new SecurityException( "Non-system callers may not flag broadcasts as alarm-related"); } } final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity(); try { try { return broadcastIntentLocked(callerApp, return broadcastIntentLocked(callerApp, Loading @@ -14458,6 +14471,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } // Not the binder call surface int broadcastIntentInPackage(String packageName, @Nullable String featureId, int uid, int broadcastIntentInPackage(String packageName, @Nullable String featureId, int uid, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, services/core/java/com/android/server/am/BroadcastRecord.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,7 @@ final class BroadcastRecord extends Binder { final boolean callerInstantApp; // caller is an Instant App? final boolean callerInstantApp; // caller is an Instant App? final boolean ordered; // serialize the send to receivers? final boolean ordered; // serialize the send to receivers? final boolean sticky; // originated from existing sticky data? final boolean sticky; // originated from existing sticky data? final boolean alarm; // originated from an alarm triggering? final boolean initialSticky; // initial broadcast from register to sticky? final boolean initialSticky; // initial broadcast from register to sticky? final int userId; // user id this broadcast was for final int userId; // user id this broadcast was for final String resolvedType; // the resolved data type final String resolvedType; // the resolved data type Loading Loading @@ -305,6 +306,7 @@ final class BroadcastRecord extends Binder { this.allowBackgroundActivityStarts = allowBackgroundActivityStarts; this.allowBackgroundActivityStarts = allowBackgroundActivityStarts; mBackgroundActivityStartsToken = backgroundActivityStartsToken; mBackgroundActivityStartsToken = backgroundActivityStartsToken; this.timeoutExempt = timeoutExempt; this.timeoutExempt = timeoutExempt; alarm = options != null && options.isAlarmBroadcast(); } } /** /** Loading Loading @@ -357,6 +359,7 @@ final class BroadcastRecord extends Binder { allowBackgroundActivityStarts = from.allowBackgroundActivityStarts; allowBackgroundActivityStarts = from.allowBackgroundActivityStarts; mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken; mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken; timeoutExempt = from.timeoutExempt; timeoutExempt = from.timeoutExempt; alarm = from.alarm; } } /** /** Loading services/core/java/com/android/server/am/PendingIntentRecord.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.am; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_SUCCESS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; Loading @@ -34,6 +35,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.IBinder; import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.ReasonCode; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.RemoteException; import android.os.TransactionTooLargeException; import android.os.TransactionTooLargeException; Loading Loading @@ -416,6 +418,22 @@ public final class PendingIntentRecord extends IIntentSender.Stub { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); final int callingPid = Binder.getCallingPid(); // Only system senders can declare a broadcast to be alarm-originated. We check // this here rather than in the general case handling below to fail before the other // invocation side effects such as allowlisting. if (options != null && callingUid != Process.SYSTEM_UID && key.type == ActivityManager.INTENT_SENDER_BROADCAST) { if (options.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) { if (DEBUG_BROADCAST_LIGHT) { Slog.w(TAG, "Non-system caller " + callingUid + " may not flag broadcast as alarm-related"); } throw new SecurityException( "Non-system callers may not flag broadcasts as alarm-related"); } } final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity(); int res = START_SUCCESS; int res = START_SUCCESS; Loading Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +11 −5 Original line number Original line Diff line number Diff line Loading @@ -335,12 +335,18 @@ public class AlarmManagerService extends SystemService { "REORDER_ALARMS_FOR_TARE", "REORDER_ALARMS_FOR_TARE", }); }); BroadcastOptions mOptsWithFgs = BroadcastOptions.makeBasic(); BroadcastOptions mOptsWithFgs = makeBasicAlarmBroadcastOptions(); BroadcastOptions mOptsWithFgsForAlarmClock = BroadcastOptions.makeBasic(); BroadcastOptions mOptsWithFgsForAlarmClock = makeBasicAlarmBroadcastOptions(); BroadcastOptions mOptsWithoutFgs = BroadcastOptions.makeBasic(); BroadcastOptions mOptsWithoutFgs = makeBasicAlarmBroadcastOptions(); BroadcastOptions mOptsTimeBroadcast = BroadcastOptions.makeBasic(); BroadcastOptions mOptsTimeBroadcast = makeBasicAlarmBroadcastOptions(); ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic(); ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic(); BroadcastOptions mBroadcastOptsRestrictBal = BroadcastOptions.makeBasic(); BroadcastOptions mBroadcastOptsRestrictBal = makeBasicAlarmBroadcastOptions(); private static BroadcastOptions makeBasicAlarmBroadcastOptions() { final BroadcastOptions b = BroadcastOptions.makeBasic(); b.setAlarmBroadcast(true); return b; } // TODO(b/172085676): Move inside alarm store. // TODO(b/172085676): Move inside alarm store. private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = Loading
core/java/android/app/BroadcastOptions.java +33 −0 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,7 @@ public class BroadcastOptions extends ComponentOptions { private String[] mRequireNoneOfPermissions; private String[] mRequireNoneOfPermissions; private long mRequireCompatChangeId = CHANGE_INVALID; private long mRequireCompatChangeId = CHANGE_INVALID; private boolean mRequireCompatChangeEnabled = true; private boolean mRequireCompatChangeEnabled = true; private boolean mIsAlarmBroadcast = false; private long mIdForResponseEvent; private long mIdForResponseEvent; /** /** Loading Loading @@ -148,6 +149,13 @@ public class BroadcastOptions extends ComponentOptions { private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = private static final String KEY_REQUIRE_COMPAT_CHANGE_ENABLED = "android:broadcast.requireCompatChangeEnabled"; "android:broadcast.requireCompatChangeEnabled"; /** * Corresponds to {@link #setAlarmBroadcast(boolean)} * @hide */ public static final String KEY_ALARM_BROADCAST = "android:broadcast.is_alarm"; /** /** * @hide * @hide * @deprecated Use {@link android.os.PowerExemptionManager# * @deprecated Use {@link android.os.PowerExemptionManager# Loading Loading @@ -207,6 +215,7 @@ public class BroadcastOptions extends ComponentOptions { mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT); mIsAlarmBroadcast = opts.getBoolean(KEY_ALARM_BROADCAST, false); } } /** /** Loading Loading @@ -498,6 +507,27 @@ public class BroadcastOptions extends ComponentOptions { mRequireCompatChangeEnabled = true; mRequireCompatChangeEnabled = true; } } /** * When set, this broadcast will be understood as having originated from an * alarm going off. Only the OS itself can use this option; uses by other * senders will be ignored. * @hide * * @param senderIsAlarm Whether the broadcast is alarm-triggered. */ public void setAlarmBroadcast(boolean senderIsAlarm) { mIsAlarmBroadcast = senderIsAlarm; } /** * Did this broadcast originate from an alarm triggering? * @return true if this broadcast is an alarm message, false otherwise * @hide */ public boolean isAlarmBroadcast() { return mIsAlarmBroadcast; } /** {@hide} */ /** {@hide} */ public long getRequireCompatChangeId() { public long getRequireCompatChangeId() { return mRequireCompatChangeId; return mRequireCompatChangeId; Loading Loading @@ -560,6 +590,9 @@ public class BroadcastOptions extends ComponentOptions { b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); } } if (mIsAlarmBroadcast) { b.putBoolean(KEY_ALARM_BROADCAST, true); } if (mMinManifestReceiverApiLevel != 0) { if (mMinManifestReceiverApiLevel != 0) { b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +14 −0 Original line number Original line Diff line number Diff line Loading @@ -14445,6 +14445,19 @@ public class ActivityManagerService extends IActivityManager.Stub final int callingPid = Binder.getCallingPid(); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); // Non-system callers can't declare that a broadcast is alarm-related. // The PendingIntent invocation case is handled in PendingIntentRecord. if (bOptions != null && callingUid != SYSTEM_UID) { if (bOptions.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) { if (DEBUG_BROADCAST) { Slog.w(TAG, "Non-system caller " + callingUid + " may not flag broadcast as alarm-related"); } throw new SecurityException( "Non-system callers may not flag broadcasts as alarm-related"); } } final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity(); try { try { return broadcastIntentLocked(callerApp, return broadcastIntentLocked(callerApp, Loading @@ -14458,6 +14471,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } // Not the binder call surface int broadcastIntentInPackage(String packageName, @Nullable String featureId, int uid, int broadcastIntentInPackage(String packageName, @Nullable String featureId, int uid, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras,
services/core/java/com/android/server/am/BroadcastRecord.java +3 −0 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,7 @@ final class BroadcastRecord extends Binder { final boolean callerInstantApp; // caller is an Instant App? final boolean callerInstantApp; // caller is an Instant App? final boolean ordered; // serialize the send to receivers? final boolean ordered; // serialize the send to receivers? final boolean sticky; // originated from existing sticky data? final boolean sticky; // originated from existing sticky data? final boolean alarm; // originated from an alarm triggering? final boolean initialSticky; // initial broadcast from register to sticky? final boolean initialSticky; // initial broadcast from register to sticky? final int userId; // user id this broadcast was for final int userId; // user id this broadcast was for final String resolvedType; // the resolved data type final String resolvedType; // the resolved data type Loading Loading @@ -305,6 +306,7 @@ final class BroadcastRecord extends Binder { this.allowBackgroundActivityStarts = allowBackgroundActivityStarts; this.allowBackgroundActivityStarts = allowBackgroundActivityStarts; mBackgroundActivityStartsToken = backgroundActivityStartsToken; mBackgroundActivityStartsToken = backgroundActivityStartsToken; this.timeoutExempt = timeoutExempt; this.timeoutExempt = timeoutExempt; alarm = options != null && options.isAlarmBroadcast(); } } /** /** Loading Loading @@ -357,6 +359,7 @@ final class BroadcastRecord extends Binder { allowBackgroundActivityStarts = from.allowBackgroundActivityStarts; allowBackgroundActivityStarts = from.allowBackgroundActivityStarts; mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken; mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken; timeoutExempt = from.timeoutExempt; timeoutExempt = from.timeoutExempt; alarm = from.alarm; } } /** /** Loading
services/core/java/com/android/server/am/PendingIntentRecord.java +18 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.am; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_SUCCESS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; Loading @@ -34,6 +35,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.IBinder; import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.ReasonCode; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.RemoteException; import android.os.TransactionTooLargeException; import android.os.TransactionTooLargeException; Loading Loading @@ -416,6 +418,22 @@ public final class PendingIntentRecord extends IIntentSender.Stub { final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); final int callingPid = Binder.getCallingPid(); // Only system senders can declare a broadcast to be alarm-originated. We check // this here rather than in the general case handling below to fail before the other // invocation side effects such as allowlisting. if (options != null && callingUid != Process.SYSTEM_UID && key.type == ActivityManager.INTENT_SENDER_BROADCAST) { if (options.containsKey(BroadcastOptions.KEY_ALARM_BROADCAST)) { if (DEBUG_BROADCAST_LIGHT) { Slog.w(TAG, "Non-system caller " + callingUid + " may not flag broadcast as alarm-related"); } throw new SecurityException( "Non-system callers may not flag broadcasts as alarm-related"); } } final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity(); int res = START_SUCCESS; int res = START_SUCCESS; Loading