Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a65e161e authored by Matthew Qin's avatar Matthew Qin Committed by Steve Kondik
Browse files

alarm: add JNI interface for clearing alarm

Add the JNI for clearing cancelled alarm, otherwise kernel driver
would know nothing about the alarm status. E.g. power-off alarm
would not be really cleared in alarm driver even it is cancelled
in the apps/framework.

Change-Id: I1250b3778de8961ba2a89d8ea8fa29d729bbc4e8
parent 3d6b8c10
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -157,6 +157,15 @@ class AlarmManagerService extends IAlarmManager.Stub {
            return alarms.get(index);
        }

        long getWhenByElapsedTime(long whenElapsed) {
            for(int i=0;i< alarms.size();i++) {
                if(alarms.get(i).whenElapsed == whenElapsed)
                    return alarms.get(i).when;
            }

            return 0;
        }

        boolean canHold(long whenElapsed, long maxWhen) {
            return (end >= whenElapsed) && (start <= maxWhen);
        }
@@ -695,7 +704,10 @@ class AlarmManagerService extends IAlarmManager.Stub {
            }
            if (firstRtcWakeup != null && mNextRtcWakeup != firstRtcWakeup.start) {
                mNextRtcWakeup = firstRtcWakeup.start;
                setLocked(RTC_POWEROFF_WAKEUP, firstRtcWakeup.start - SystemClock.elapsedRealtime());
                long when = firstRtcWakeup.getWhenByElapsedTime(mNextRtcWakeup);
                if (when != 0) {
                    setLocked(RTC_POWEROFF_WAKEUP, when);
                }
            }

        }
@@ -763,6 +775,20 @@ class AlarmManagerService extends IAlarmManager.Stub {
        boolean didRemove = false;
        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
            Batch b = mAlarmBatches.get(i);
            ArrayList<Alarm> alarmList = b.alarms;
            Alarm alarm = null;
            for (int j = alarmList.size() - 1; j >= 0; j--) {
                alarm = alarmList.get(j);
                if (alarm.type == RTC_POWEROFF_WAKEUP && alarm.operation.equals(operation)) {
                    long alarmSeconds, alarmNanoseconds;
                    alarmSeconds = alarm.when / 1000;
                    alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000;
                    Slog.w(TAG,"Clear alarm type=" + alarm.type + ",alarmSeconds=" +
                       alarmSeconds);
                    clear(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);
                    mNextRtcWakeup = 0;
                }
            }
            didRemove |= b.remove(operation);
            if (b.size() == 0) {
                mAlarmBatches.remove(i);
@@ -1050,6 +1076,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
    private native int init();
    private native void close(int fd);
    private native void set(int fd, int type, long seconds, long nanoseconds);
    private native void clear(int fd, int type, long seconds, long nanoseconds);
    private native int waitForAlarm(int fd);
    private native int setKernelTimezone(int fd, int minuteswest);

+14 −0
Original line number Diff line number Diff line
@@ -78,6 +78,19 @@ static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jin
    }
}

static void android_server_AlarmManagerService_clear(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
{
	struct timespec ts;
	ts.tv_sec = seconds;
	ts.tv_nsec = nanoseconds;

	int result = ioctl(fd, ANDROID_ALARM_CLEAR(type), &ts);
	if (result < 0)
	{
	    ALOGE("Unable to clear alarm %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
	}
}

static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)
{
	int result = 0;
@@ -101,6 +114,7 @@ static JNINativeMethod sMethods[] = {
	{"init", "()I", (void*)android_server_AlarmManagerService_init},
	{"close", "(I)V", (void*)android_server_AlarmManagerService_close},
	{"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set},
	{"clear", "(IIJJ)V", (void*)android_server_AlarmManagerService_clear},
    {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm},
    {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone},
};