If you set an alarm before the epoch, you're gonna have a bad time
For apps build against the KLP+ SDK, this will now throw an illegal argument
exception. Legacy apps will simply see the alarm delivered immediately.
Bug 9965704
Change-Id: Ia103d9529d32640098be324820fe228efa95431d
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index d9c3775..557bd6c 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -257,6 +257,14 @@
private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
PendingIntent operation) {
+ if (triggerAtMillis < 0) {
+ if (mAlwaysExact) {
+ // Fatal error for KLP+ apps to use negative trigger times
+ throw new IllegalArgumentException("Invalid alarm trigger time "
+ + triggerAtMillis);
+ }
+ triggerAtMillis = 0;
+ }
try {
mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation);
} catch (RemoteException ex) {
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 39c0bdd..1ba79ae 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -521,6 +521,14 @@
throw new IllegalArgumentException("Invalid alarm type " + type);
}
+ if (triggerAtTime < 0) {
+ final long who = Binder.getCallingUid();
+ final long what = Binder.getCallingPid();
+ Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + who
+ + " pid=" + what);
+ triggerAtTime = 0;
+ }
+
final long nowElapsed = SystemClock.elapsedRealtime();
final long triggerElapsed = convertToElapsed(triggerAtTime, type);
final long maxElapsed;
@@ -567,7 +575,12 @@
}
if (DEBUG_VALIDATE) {
- if (doValidate && validateConsistencyLocked()) {
+ if (doValidate && !validateConsistencyLocked()) {
+ Slog.v(TAG, "Tipping-point operation: type=" + type + " when=" + when
+ + " when(hex)=" + Long.toHexString(when)
+ + " whenElapsed=" + whenElapsed + " maxWhen=" + maxWhen
+ + " interval=" + interval + " op=" + operation
+ + " standalone=" + isStandalone);
rebatchAllAlarmsLocked(false);
reschedule = true;
}
@@ -586,8 +599,9 @@
final int NZ = mAlarmBatches.size();
for (int iz = 0; iz < NZ; iz++) {
Batch bz = mAlarmBatches.get(iz);
- Slog.v(TAG, "Batch " + iz + ": " + bz);
+ pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz);
dumpAlarmList(pw, bz.alarms, " ", nowELAPSED, nowRTC);
+ pw.flush();
Slog.v(TAG, bs.toString());
bs.reset();
}