Loading services/java/com/android/server/AlarmManagerService.java +14 −14 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ class AlarmManagerService extends SystemService { final Object mLock = new Object(); int mDescriptor; long mNativeData; private long mNextWakeup; private long mNextNonWakeup; int mBroadcastRefCount = 0; Loading Loading @@ -462,7 +462,7 @@ class AlarmManagerService extends SystemService { @Override public void onStart() { mDescriptor = init(); mNativeData = init(); mNextWakeup = mNextNonWakeup = 0; // We have to set current TimeZone info to kernel Loading @@ -488,7 +488,7 @@ class AlarmManagerService extends SystemService { mClockReceiver.scheduleDateChangedEvent(); mUninstallReceiver = new UninstallReceiver(); if (mDescriptor != -1) { if (mNativeData != 0) { AlarmThread waitThread = new AlarmThread(); waitThread.start(); } else { Loading @@ -501,7 +501,7 @@ class AlarmManagerService extends SystemService { @Override protected void finalize() throws Throwable { try { close(mDescriptor); close(mNativeData); } finally { super.finalize(); } Loading Loading @@ -529,7 +529,7 @@ class AlarmManagerService extends SystemService { // Update the kernel timezone information // Kernel tracks time offsets as 'minutes west of GMT' int gmtOffset = zone.getOffset(System.currentTimeMillis()); setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); setKernelTimezone(mNativeData, -(gmtOffset / 60000)); } TimeZone.setDefault(null); Loading Loading @@ -975,7 +975,7 @@ class AlarmManagerService extends SystemService { } private void setLocked(int type, long when) { if (mDescriptor != -1) { if (mNativeData != 0) { // The kernel never triggers alarms with negative wakeup times // so we ensure they are positive. long alarmSeconds, alarmNanoseconds; Loading @@ -987,7 +987,7 @@ class AlarmManagerService extends SystemService { alarmNanoseconds = (when % 1000) * 1000 * 1000; } set(mDescriptor, type, alarmSeconds, alarmNanoseconds); set(mNativeData, type, alarmSeconds, alarmNanoseconds); } else { Message msg = Message.obtain(); msg.what = ALARM_EVENT; Loading Loading @@ -1031,11 +1031,11 @@ class AlarmManagerService extends SystemService { } } private native int init(); private native void close(int fd); private native void set(int fd, int type, long seconds, long nanoseconds); private native int waitForAlarm(int fd); private native int setKernelTimezone(int fd, int minuteswest); 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 waitForAlarm(long nativeData); private native int setKernelTimezone(long nativeData, int minuteswest); void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) { // batches are temporally sorted, so we need only pull from the Loading Loading @@ -1175,7 +1175,7 @@ class AlarmManagerService extends SystemService { while (true) { int result = waitForAlarm(mDescriptor); int result = waitForAlarm(mNativeData); triggerList.clear(); Loading Loading @@ -1357,7 +1357,7 @@ class AlarmManagerService extends SystemService { // daylight savings information. TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); int gmtOffset = zone.getOffset(System.currentTimeMillis()); setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); setKernelTimezone(mNativeData, -(gmtOffset / 60000)); scheduleDateChangedEvent(); } } Loading services/jni/com_android_server_AlarmManagerService.cpp +221 −14 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/epoll.h> #include <sys/timerfd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> Loading @@ -37,7 +39,136 @@ namespace android { static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jint, jint minswest) static const size_t N_ANDROID_TIMERFDS = ANDROID_ALARM_TYPE_COUNT + 1; static const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = { CLOCK_REALTIME_ALARM, CLOCK_REALTIME, CLOCK_BOOTTIME_ALARM, CLOCK_BOOTTIME, CLOCK_MONOTONIC, CLOCK_REALTIME, }; /* to match the legacy alarm driver implementation, we need an extra CLOCK_REALTIME fd which exists specifically to be canceled on RTC changes */ class AlarmImpl { public: AlarmImpl(int *fds, size_t n_fds); virtual ~AlarmImpl(); virtual int set(int type, struct timespec *ts) = 0; virtual int waitForAlarm() = 0; protected: int *fds; size_t n_fds; }; class AlarmImplAlarmDriver : public AlarmImpl { public: AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { } int set(int type, struct timespec *ts); int waitForAlarm(); }; class AlarmImplTimerFd : public AlarmImpl { public: AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd) : AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd) { } ~AlarmImplTimerFd(); int set(int type, struct timespec *ts); int waitForAlarm(); private: int epollfd; }; AlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]), n_fds(n_fds) { memcpy(fds, fds_, n_fds * sizeof(fds[0])); } AlarmImpl::~AlarmImpl() { for (size_t i = 0; i < n_fds; i++) { close(fds[i]); } delete [] fds; } int AlarmImplAlarmDriver::set(int type, struct timespec *ts) { return ioctl(fds[0], ANDROID_ALARM_SET(type), ts); } int AlarmImplAlarmDriver::waitForAlarm() { return ioctl(fds[0], ANDROID_ALARM_WAIT); } AlarmImplTimerFd::~AlarmImplTimerFd() { for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { epoll_ctl(epollfd, EPOLL_CTL_DEL, fds[i], NULL); } close(epollfd); } int AlarmImplTimerFd::set(int type, struct timespec *ts) { if (type > ANDROID_ALARM_TYPE_COUNT) { errno = EINVAL; return -1; } if (!ts->tv_nsec && !ts->tv_sec) { ts->tv_nsec = 1; } /* timerfd interprets 0 = disarm, so replace with a practically equivalent deadline of 1 ns */ struct itimerspec spec; memset(&spec, 0, sizeof(spec)); memcpy(&spec.it_value, ts, sizeof(spec.it_value)); return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL); } int AlarmImplTimerFd::waitForAlarm() { epoll_event events[N_ANDROID_TIMERFDS]; int nevents = epoll_wait(epollfd, events, N_ANDROID_TIMERFDS, -1); if (nevents < 0) { return nevents; } int result = 0; for (int i = 0; i < nevents; i++) { uint32_t alarm_idx = events[i].data.u32; uint64_t unused; ssize_t err = read(fds[alarm_idx], &unused, sizeof(unused)); if (err < 0) { if (alarm_idx == ANDROID_ALARM_TYPE_COUNT && errno == ECANCELED) { result |= ANDROID_ALARM_TIME_CHANGE_MASK; } else { return err; } } else { result |= (1 << alarm_idx); } } return result; } static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest) { struct timezone tz; Loading @@ -55,36 +186,112 @@ static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobjec return 0; } static jint android_server_AlarmManagerService_init(JNIEnv*, jobject) static jlong init_alarm_driver() { return open("/dev/alarm", O_RDWR); int fd = open("/dev/alarm", O_RDWR); if (fd < 0) { ALOGV("opening alarm driver failed: %s", strerror(errno)); return 0; } AlarmImpl *ret = new AlarmImplAlarmDriver(fd); return reinterpret_cast<jlong>(ret); } static jlong init_timerfd() { int epollfd; int fds[N_ANDROID_TIMERFDS]; epollfd = epoll_create(N_ANDROID_TIMERFDS); if (epollfd < 0) { ALOGV("epoll_create(%u) failed: %s", N_ANDROID_TIMERFDS, strerror(errno)); return 0; } for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { fds[i] = timerfd_create(android_alarm_to_clockid[i], 0); if (fds[i] < 0) { ALOGV("timerfd_create(%u) failed: %s", android_alarm_to_clockid[i], strerror(errno)); close(epollfd); for (size_t j = 0; j < i; j++) { close(fds[j]); } return 0; } } AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd); for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { epoll_event event; event.events = EPOLLIN | EPOLLWAKEUP; event.data.u32 = i; int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event); if (err < 0) { ALOGV("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); delete ret; return 0; } } struct itimerspec spec; memset(&spec, 0, sizeof(spec)); /* 0 = disarmed; the timerfd doesn't need to be armed to get RTC change notifications, just set up as cancelable */ int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT], TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL); if (err < 0) { ALOGV("timerfd_settime() failed: %s", strerror(errno)); delete ret; return 0; } return reinterpret_cast<jlong>(ret); } static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) { jlong ret = init_alarm_driver(); if (ret) { return ret; } return init_timerfd(); } static void android_server_AlarmManagerService_close(JNIEnv*, jobject, jint fd) static void android_server_AlarmManagerService_close(JNIEnv*, jobject, jlong nativeData) { close(fd); AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); delete impl; } static void android_server_AlarmManagerService_set(JNIEnv*, jobject, jint fd, jint type, jlong seconds, jlong nanoseconds) static void 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 = ioctl(fd, ANDROID_ALARM_SET(type), &ts); int result = impl->set(type, &ts); if (result < 0) { ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno)); } } static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jint fd) static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jlong nativeData) { AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); int result = 0; do { result = ioctl(fd, ANDROID_ALARM_WAIT); result = impl->waitForAlarm(); } while (result < 0 && errno == EINTR); if (result < 0) Loading @@ -98,11 +305,11 @@ static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, ji static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"init", "()I", (void*)android_server_AlarmManagerService_init}, {"close", "(I)V", (void*)android_server_AlarmManagerService_close}, {"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set}, {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm}, {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, {"init", "()J", (void*)android_server_AlarmManagerService_init}, {"close", "(J)V", (void*)android_server_AlarmManagerService_close}, {"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set}, {"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm}, {"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, }; int register_android_server_AlarmManagerService(JNIEnv* env) Loading Loading
services/java/com/android/server/AlarmManagerService.java +14 −14 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ class AlarmManagerService extends SystemService { final Object mLock = new Object(); int mDescriptor; long mNativeData; private long mNextWakeup; private long mNextNonWakeup; int mBroadcastRefCount = 0; Loading Loading @@ -462,7 +462,7 @@ class AlarmManagerService extends SystemService { @Override public void onStart() { mDescriptor = init(); mNativeData = init(); mNextWakeup = mNextNonWakeup = 0; // We have to set current TimeZone info to kernel Loading @@ -488,7 +488,7 @@ class AlarmManagerService extends SystemService { mClockReceiver.scheduleDateChangedEvent(); mUninstallReceiver = new UninstallReceiver(); if (mDescriptor != -1) { if (mNativeData != 0) { AlarmThread waitThread = new AlarmThread(); waitThread.start(); } else { Loading @@ -501,7 +501,7 @@ class AlarmManagerService extends SystemService { @Override protected void finalize() throws Throwable { try { close(mDescriptor); close(mNativeData); } finally { super.finalize(); } Loading Loading @@ -529,7 +529,7 @@ class AlarmManagerService extends SystemService { // Update the kernel timezone information // Kernel tracks time offsets as 'minutes west of GMT' int gmtOffset = zone.getOffset(System.currentTimeMillis()); setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); setKernelTimezone(mNativeData, -(gmtOffset / 60000)); } TimeZone.setDefault(null); Loading Loading @@ -975,7 +975,7 @@ class AlarmManagerService extends SystemService { } private void setLocked(int type, long when) { if (mDescriptor != -1) { if (mNativeData != 0) { // The kernel never triggers alarms with negative wakeup times // so we ensure they are positive. long alarmSeconds, alarmNanoseconds; Loading @@ -987,7 +987,7 @@ class AlarmManagerService extends SystemService { alarmNanoseconds = (when % 1000) * 1000 * 1000; } set(mDescriptor, type, alarmSeconds, alarmNanoseconds); set(mNativeData, type, alarmSeconds, alarmNanoseconds); } else { Message msg = Message.obtain(); msg.what = ALARM_EVENT; Loading Loading @@ -1031,11 +1031,11 @@ class AlarmManagerService extends SystemService { } } private native int init(); private native void close(int fd); private native void set(int fd, int type, long seconds, long nanoseconds); private native int waitForAlarm(int fd); private native int setKernelTimezone(int fd, int minuteswest); 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 waitForAlarm(long nativeData); private native int setKernelTimezone(long nativeData, int minuteswest); void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) { // batches are temporally sorted, so we need only pull from the Loading Loading @@ -1175,7 +1175,7 @@ class AlarmManagerService extends SystemService { while (true) { int result = waitForAlarm(mDescriptor); int result = waitForAlarm(mNativeData); triggerList.clear(); Loading Loading @@ -1357,7 +1357,7 @@ class AlarmManagerService extends SystemService { // daylight savings information. TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY)); int gmtOffset = zone.getOffset(System.currentTimeMillis()); setKernelTimezone(mDescriptor, -(gmtOffset / 60000)); setKernelTimezone(mNativeData, -(gmtOffset / 60000)); scheduleDateChangedEvent(); } } Loading
services/jni/com_android_server_AlarmManagerService.cpp +221 −14 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ #include <fcntl.h> #include <stdio.h> #include <string.h> #include <sys/epoll.h> #include <sys/timerfd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> Loading @@ -37,7 +39,136 @@ namespace android { static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jint, jint minswest) static const size_t N_ANDROID_TIMERFDS = ANDROID_ALARM_TYPE_COUNT + 1; static const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = { CLOCK_REALTIME_ALARM, CLOCK_REALTIME, CLOCK_BOOTTIME_ALARM, CLOCK_BOOTTIME, CLOCK_MONOTONIC, CLOCK_REALTIME, }; /* to match the legacy alarm driver implementation, we need an extra CLOCK_REALTIME fd which exists specifically to be canceled on RTC changes */ class AlarmImpl { public: AlarmImpl(int *fds, size_t n_fds); virtual ~AlarmImpl(); virtual int set(int type, struct timespec *ts) = 0; virtual int waitForAlarm() = 0; protected: int *fds; size_t n_fds; }; class AlarmImplAlarmDriver : public AlarmImpl { public: AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { } int set(int type, struct timespec *ts); int waitForAlarm(); }; class AlarmImplTimerFd : public AlarmImpl { public: AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd) : AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd) { } ~AlarmImplTimerFd(); int set(int type, struct timespec *ts); int waitForAlarm(); private: int epollfd; }; AlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]), n_fds(n_fds) { memcpy(fds, fds_, n_fds * sizeof(fds[0])); } AlarmImpl::~AlarmImpl() { for (size_t i = 0; i < n_fds; i++) { close(fds[i]); } delete [] fds; } int AlarmImplAlarmDriver::set(int type, struct timespec *ts) { return ioctl(fds[0], ANDROID_ALARM_SET(type), ts); } int AlarmImplAlarmDriver::waitForAlarm() { return ioctl(fds[0], ANDROID_ALARM_WAIT); } AlarmImplTimerFd::~AlarmImplTimerFd() { for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { epoll_ctl(epollfd, EPOLL_CTL_DEL, fds[i], NULL); } close(epollfd); } int AlarmImplTimerFd::set(int type, struct timespec *ts) { if (type > ANDROID_ALARM_TYPE_COUNT) { errno = EINVAL; return -1; } if (!ts->tv_nsec && !ts->tv_sec) { ts->tv_nsec = 1; } /* timerfd interprets 0 = disarm, so replace with a practically equivalent deadline of 1 ns */ struct itimerspec spec; memset(&spec, 0, sizeof(spec)); memcpy(&spec.it_value, ts, sizeof(spec.it_value)); return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL); } int AlarmImplTimerFd::waitForAlarm() { epoll_event events[N_ANDROID_TIMERFDS]; int nevents = epoll_wait(epollfd, events, N_ANDROID_TIMERFDS, -1); if (nevents < 0) { return nevents; } int result = 0; for (int i = 0; i < nevents; i++) { uint32_t alarm_idx = events[i].data.u32; uint64_t unused; ssize_t err = read(fds[alarm_idx], &unused, sizeof(unused)); if (err < 0) { if (alarm_idx == ANDROID_ALARM_TYPE_COUNT && errno == ECANCELED) { result |= ANDROID_ALARM_TIME_CHANGE_MASK; } else { return err; } } else { result |= (1 << alarm_idx); } } return result; } static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest) { struct timezone tz; Loading @@ -55,36 +186,112 @@ static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobjec return 0; } static jint android_server_AlarmManagerService_init(JNIEnv*, jobject) static jlong init_alarm_driver() { return open("/dev/alarm", O_RDWR); int fd = open("/dev/alarm", O_RDWR); if (fd < 0) { ALOGV("opening alarm driver failed: %s", strerror(errno)); return 0; } AlarmImpl *ret = new AlarmImplAlarmDriver(fd); return reinterpret_cast<jlong>(ret); } static jlong init_timerfd() { int epollfd; int fds[N_ANDROID_TIMERFDS]; epollfd = epoll_create(N_ANDROID_TIMERFDS); if (epollfd < 0) { ALOGV("epoll_create(%u) failed: %s", N_ANDROID_TIMERFDS, strerror(errno)); return 0; } for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { fds[i] = timerfd_create(android_alarm_to_clockid[i], 0); if (fds[i] < 0) { ALOGV("timerfd_create(%u) failed: %s", android_alarm_to_clockid[i], strerror(errno)); close(epollfd); for (size_t j = 0; j < i; j++) { close(fds[j]); } return 0; } } AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd); for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { epoll_event event; event.events = EPOLLIN | EPOLLWAKEUP; event.data.u32 = i; int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event); if (err < 0) { ALOGV("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); delete ret; return 0; } } struct itimerspec spec; memset(&spec, 0, sizeof(spec)); /* 0 = disarmed; the timerfd doesn't need to be armed to get RTC change notifications, just set up as cancelable */ int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT], TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL); if (err < 0) { ALOGV("timerfd_settime() failed: %s", strerror(errno)); delete ret; return 0; } return reinterpret_cast<jlong>(ret); } static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) { jlong ret = init_alarm_driver(); if (ret) { return ret; } return init_timerfd(); } static void android_server_AlarmManagerService_close(JNIEnv*, jobject, jint fd) static void android_server_AlarmManagerService_close(JNIEnv*, jobject, jlong nativeData) { close(fd); AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); delete impl; } static void android_server_AlarmManagerService_set(JNIEnv*, jobject, jint fd, jint type, jlong seconds, jlong nanoseconds) static void 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 = ioctl(fd, ANDROID_ALARM_SET(type), &ts); int result = impl->set(type, &ts); if (result < 0) { ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno)); } } static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jint fd) static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jlong nativeData) { AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); int result = 0; do { result = ioctl(fd, ANDROID_ALARM_WAIT); result = impl->waitForAlarm(); } while (result < 0 && errno == EINTR); if (result < 0) Loading @@ -98,11 +305,11 @@ static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, ji static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"init", "()I", (void*)android_server_AlarmManagerService_init}, {"close", "(I)V", (void*)android_server_AlarmManagerService_close}, {"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set}, {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm}, {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, {"init", "()J", (void*)android_server_AlarmManagerService_init}, {"close", "(J)V", (void*)android_server_AlarmManagerService_close}, {"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set}, {"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm}, {"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, }; int register_android_server_AlarmManagerService(JNIEnv* env) Loading