Declare a WTF if setting an alarm fails
This doesn't crash, but does trigger incident reporting.
Also adjust the dumpsys output to be a bit more sensible, and to include
not only last-wakeup but also last-trigger breadcrumbs.
Bug: 65489393
Test: manual
Change-Id: Ifb11f673ad5242b0320092731c9d8311a29f1170
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 7ab5812..4b91d39 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -55,6 +55,7 @@
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
+import android.system.Os;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.ArrayMap;
@@ -158,6 +159,7 @@
private long mNextNonWakeup;
private long mLastWakeupSet;
private long mLastWakeup;
+ private long mLastTrigger;
private long mLastTickSet;
private long mLastTickIssued; // elapsed
private long mLastTickReceived;
@@ -1851,12 +1853,17 @@
long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED);
pw.print(" Next non-wakeup alarm: ");
TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw);
+ pw.print(" = "); pw.print(mNextNonWakeup);
pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC)));
- pw.print(" Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
+ pw.print(" Next wakeup alarm: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
+ pw.print(" = "); pw.print(mNextWakeup);
pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC)));
+ pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw);
+ pw.println();
pw.print(" Last wakeup: "); TimeUtils.formatDuration(mLastWakeup, nowELAPSED, pw);
- pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw);
- pw.println();
+ pw.print(" = "); pw.println(mLastWakeup);
+ pw.print(" Last trigger: "); TimeUtils.formatDuration(mLastTrigger, nowELAPSED, pw);
+ pw.print(" = "); pw.println(mLastTrigger);
pw.print(" Num time change events: "); pw.println(mNumTimeChanged);
pw.println();
@@ -2884,7 +2891,14 @@
alarmNanoseconds = (when % 1000) * 1000 * 1000;
}
- set(mNativeData, type, alarmSeconds, alarmNanoseconds);
+ final int result = set(mNativeData, type, alarmSeconds, alarmNanoseconds);
+ if (result != 0) {
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ Slog.wtf(TAG, "Unable to set kernel alarm, now=" + nowElapsed
+ + " type=" + type + " when=" + when
+ + " @ (" + alarmSeconds + "," + alarmNanoseconds
+ + "), ret = " + result + " = " + Os.strerror(result));
+ }
} else {
Message msg = Message.obtain();
msg.what = ALARM_EVENT;
@@ -2944,7 +2958,7 @@
private native long init();
private native void close(long nativeData);
- private native void set(long nativeData, int type, long seconds, long nanoseconds);
+ private native int set(long nativeData, int type, long seconds, long nanoseconds);
private native int waitForAlarm(long nativeData);
private native int setKernelTime(long nativeData, long millis);
private native int setKernelTimezone(long nativeData, int minuteswest);
@@ -3363,12 +3377,14 @@
while (true)
{
int result = waitForAlarm(mNativeData);
- mLastWakeup = SystemClock.elapsedRealtime();
-
- triggerList.clear();
final long nowRTC = System.currentTimeMillis();
final long nowELAPSED = SystemClock.elapsedRealtime();
+ synchronized (mLock) {
+ mLastWakeup = nowELAPSED;
+ }
+
+ triggerList.clear();
if ((result & TIME_CHANGED_MASK) != 0) {
// The kernel can give us spurious time change notifications due to
@@ -3434,6 +3450,7 @@
}
}
+ mLastTrigger = nowELAPSED;
boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
// if there are no wakeup alarms and the screen is off, we can
diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp
index bcb0b4f..47350c1 100644
--- a/services/core/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/core/jni/com_android_server_AlarmManagerService.cpp
@@ -385,20 +385,21 @@
delete impl;
}
-static void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativeData, jint type, jlong seconds, jlong nanoseconds)
+static jint android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativeData, jint type, jlong seconds, jlong nanoseconds)
{
AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
struct timespec ts;
ts.tv_sec = seconds;
ts.tv_nsec = nanoseconds;
- int result = impl->set(type, &ts);
+ const int result = impl->set(type, &ts);
if (result < 0)
{
ALOGE("Unable to set alarm to %lld.%09lld: %s\n",
static_cast<long long>(seconds),
static_cast<long long>(nanoseconds), strerror(errno));
}
+ return result >= 0 ? 0 : errno;
}
static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jlong nativeData)
@@ -424,7 +425,7 @@
/* name, signature, funcPtr */
{"init", "()J", (void*)android_server_AlarmManagerService_init},
{"close", "(J)V", (void*)android_server_AlarmManagerService_close},
- {"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set},
+ {"set", "(JIJJ)I", (void*)android_server_AlarmManagerService_set},
{"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm},
{"setKernelTime", "(JJ)I", (void*)android_server_AlarmManagerService_setKernelTime},
{"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone},