com_android_server_AlarmManagerService.cpp revision 76f6a86de25e1bf74717e047e55fd44b089673f3
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* //device/libs/android_runtime/android_server_AlarmManagerService.cpp 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2006, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 5dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** Licensed under the Apache License, Version 2.0 (the "License"); 6dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** you may not use this file except in compliance with the License. 7dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 9dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 11dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** Unless required by applicable law or agreed to in writing, software 12dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** distributed under the License is distributed on an "AS IS" BASIS, 13dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "AlarmManagerService" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 2225ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <utils/Log.h> 2325ba5b6564224dceefa086b5c439ef28dad530caMathias Agopian#include <utils/misc.h> 240eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann#include <utils/String8.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 260eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann#include <dirent.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 30a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann#include <sys/epoll.h> 31a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann#include <sys/timerfd.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/socket.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <arpa/inet.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/in.h> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/ioctl.h> 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/android_alarm.h> 4138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann#include <linux/rtc.h> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 45a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic const size_t N_ANDROID_TIMERFDS = ANDROID_ALARM_TYPE_COUNT + 1; 46a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = { 47a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME_ALARM, 48a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME, 49a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_BOOTTIME_ALARM, 50a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_BOOTTIME, 51a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_MONOTONIC, 52a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME, 53a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 54a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann/* to match the legacy alarm driver implementation, we need an extra 55a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME fd which exists specifically to be canceled on RTC changes */ 56a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 57a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannclass AlarmImpl 58a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 59a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannpublic: 60a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl(int *fds, size_t n_fds); 61a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann virtual ~AlarmImpl(); 62a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 63a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann virtual int set(int type, struct timespec *ts) = 0; 6438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann virtual int setTime(struct timeval *tv) = 0; 65a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann virtual int waitForAlarm() = 0; 66a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 67a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannprotected: 68a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int *fds; 69a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann size_t n_fds; 70a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 71a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 72a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannclass AlarmImplAlarmDriver : public AlarmImpl 73a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 74a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannpublic: 75a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { } 76a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 77a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int set(int type, struct timespec *ts); 7838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann int setTime(struct timeval *tv); 79a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int waitForAlarm(); 80a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 81a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 82a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannclass AlarmImplTimerFd : public AlarmImpl 83a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 84a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannpublic: 850eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd, int rtc_id) : 860eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd), rtc_id(rtc_id) { } 87a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ~AlarmImplTimerFd(); 88a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 89a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int set(int type, struct timespec *ts); 9038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann int setTime(struct timeval *tv); 91a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int waitForAlarm(); 92a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 93a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannprivate: 94a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int epollfd; 950eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann int rtc_id; 96a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 97a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 98a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]), 99a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann n_fds(n_fds) 100a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 101a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memcpy(fds, fds_, n_fds * sizeof(fds[0])); 102a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 103a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 104a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImpl::~AlarmImpl() 105a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 106a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < n_fds; i++) { 107a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(fds[i]); 108a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 109a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete [] fds; 110a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 111a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 112a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplAlarmDriver::set(int type, struct timespec *ts) 113a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 114a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return ioctl(fds[0], ANDROID_ALARM_SET(type), ts); 115a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 116a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 11738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmannint AlarmImplAlarmDriver::setTime(struct timeval *tv) 11838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann{ 11938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann struct timespec ts; 12038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann int res; 12138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 12238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ts.tv_sec = tv->tv_sec; 12338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ts.tv_nsec = tv->tv_usec * 1000; 12438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann res = ioctl(fds[0], ANDROID_ALARM_SET_RTC, &ts); 12538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann if (res < 0) 12638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ALOGV("ANDROID_ALARM_SET_RTC ioctl failed: %s\n", strerror(errno)); 12738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann return res; 12838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann} 12938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 130a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplAlarmDriver::waitForAlarm() 131a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 132a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return ioctl(fds[0], ANDROID_ALARM_WAIT); 133a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 134a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 135a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImplTimerFd::~AlarmImplTimerFd() 136a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 137a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { 138a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epoll_ctl(epollfd, EPOLL_CTL_DEL, fds[i], NULL); 139a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 140a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(epollfd); 141a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 142a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 143a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplTimerFd::set(int type, struct timespec *ts) 144a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 145a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (type > ANDROID_ALARM_TYPE_COUNT) { 146a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann errno = EINVAL; 147a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return -1; 148a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 149a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 150a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (!ts->tv_nsec && !ts->tv_sec) { 151a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ts->tv_nsec = 1; 152a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 153a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann /* timerfd interprets 0 = disarm, so replace with a practically 154a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann equivalent deadline of 1 ns */ 155a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 156a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann struct itimerspec spec; 157a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memset(&spec, 0, sizeof(spec)); 158a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memcpy(&spec.it_value, ts, sizeof(spec.it_value)); 159a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 160a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL); 161a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 162a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 16338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmannint AlarmImplTimerFd::setTime(struct timeval *tv) 16438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann{ 16538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann struct rtc_time rtc; 16638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann struct tm tm, *gmtime_res; 16738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann int fd; 16838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann int res; 16938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 17038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann res = settimeofday(tv, NULL); 17138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann if (res < 0) { 17238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ALOGV("settimeofday() failed: %s\n", strerror(errno)); 173c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann return -1; 174c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann } 175c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann 1760eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (rtc_id < 0) { 1770eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGV("Not setting RTC because wall clock RTC was not found"); 1780eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann errno = ENODEV; 1790eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann return -1; 1800eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann } 1810eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 1820eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann android::String8 rtc_dev = String8::format("/dev/rtc%d", rtc_id); 1830eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann fd = open(rtc_dev.string(), O_RDWR); 184c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann if (fd < 0) { 1850eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGV("Unable to open %s: %s\n", rtc_dev.string(), strerror(errno)); 186c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann return res; 18738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann } 18838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 18938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann gmtime_res = gmtime_r(&tv->tv_sec, &tm); 19038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann if (!gmtime_res) { 19138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ALOGV("gmtime_r() failed: %s\n", strerror(errno)); 19238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann res = -1; 19338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann goto done; 19438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann } 19538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 19638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann memset(&rtc, 0, sizeof(rtc)); 19738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_sec = tm.tm_sec; 19838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_min = tm.tm_min; 19938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_hour = tm.tm_hour; 20038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_mday = tm.tm_mday; 20138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_mon = tm.tm_mon; 20238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_year = tm.tm_year; 20338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_wday = tm.tm_wday; 20438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_yday = tm.tm_yday; 20538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann rtc.tm_isdst = tm.tm_isdst; 20638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann res = ioctl(fd, RTC_SET_TIME, &rtc); 20738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann if (res < 0) 20838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ALOGV("RTC_SET_TIME ioctl failed: %s\n", strerror(errno)); 20938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmanndone: 21038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann close(fd); 21138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann return res; 21238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann} 21338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 214a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplTimerFd::waitForAlarm() 215a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 216a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epoll_event events[N_ANDROID_TIMERFDS]; 217a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 218a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int nevents = epoll_wait(epollfd, events, N_ANDROID_TIMERFDS, -1); 219a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (nevents < 0) { 220a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return nevents; 221a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 222a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 223a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int result = 0; 224a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (int i = 0; i < nevents; i++) { 225a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann uint32_t alarm_idx = events[i].data.u32; 226a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann uint64_t unused; 227a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ssize_t err = read(fds[alarm_idx], &unused, sizeof(unused)); 228a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (err < 0) { 229a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (alarm_idx == ANDROID_ALARM_TYPE_COUNT && errno == ECANCELED) { 230a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann result |= ANDROID_ALARM_TIME_CHANGE_MASK; 231a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } else { 232a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return err; 233a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 234a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } else { 235a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann result |= (1 << alarm_idx); 236a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 237a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 238a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 239a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return result; 240a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 241a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 24238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmannstatic jint android_server_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis) 24338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann{ 24438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 24538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann struct timeval tv; 24638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann int ret; 24738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 24838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann if (millis <= 0 || millis / 1000LL >= INT_MAX) { 24938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann return -1; 25038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann } 25138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 25238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann tv.tv_sec = (time_t) (millis / 1000LL); 25338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL); 25438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 25538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec); 25638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 25738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ret = impl->setTime(&tv); 25838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 25938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann if(ret < 0) { 26038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno)); 26138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann ret = -1; 26238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann } 26338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann return ret; 26438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann} 26538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann 266a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest) 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timezone tz; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tz.tz_minuteswest = minswest; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tz.tz_dsttime = 0; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = settimeofday(NULL, &tz); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result < 0) { 2753762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno)); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2785baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 284a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jlong init_alarm_driver() 285a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 286a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int fd = open("/dev/alarm", O_RDWR); 287a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (fd < 0) { 288a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("opening alarm driver failed: %s", strerror(errno)); 289a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 290a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 291a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 292a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *ret = new AlarmImplAlarmDriver(fd); 293a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return reinterpret_cast<jlong>(ret); 294a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 295a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 2960eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmannstatic const char rtc_sysfs[] = "/sys/class/rtc"; 2970eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 2980eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmannstatic bool rtc_is_hctosys(unsigned int rtc_id) 2990eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann{ 3000eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann android::String8 hctosys_path = String8::format("%s/rtc%u/hctosys", 3010eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann rtc_sysfs, rtc_id); 3020eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3030eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann FILE *file = fopen(hctosys_path.string(), "re"); 3040eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (!file) { 3050eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGE("failed to open %s: %s", hctosys_path.string(), strerror(errno)); 3060eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann return false; 3070eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann } 3080eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3090eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann unsigned int hctosys; 3100eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann bool ret = false; 3110eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann int err = fscanf(file, "%u", &hctosys); 3120eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (err == EOF) 3130eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGE("failed to read from %s: %s", hctosys_path.string(), 3140eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann strerror(errno)); 3150eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann else if (err == 0) 3160eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGE("%s did not have expected contents", hctosys_path.string()); 3170eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann else 3180eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ret = hctosys; 3190eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3200eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann fclose(file); 3210eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann return ret; 3220eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann} 3230eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3240eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmannstatic int wall_clock_rtc() 3250eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann{ 3260eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann DIR *dir = opendir(rtc_sysfs); 3270eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (!dir) { 3280eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGE("failed to open %s: %s", rtc_sysfs, strerror(errno)); 3290eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann return -1; 3300eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann } 3310eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3320eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann struct dirent *dirent; 3330eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann while (errno = 0, dirent = readdir(dir)) { 3340eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann unsigned int rtc_id; 3350eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id); 3360eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3370eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (matched < 0) 3380eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann break; 3390eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann else if (matched != 1) 3400eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann continue; 3410eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3420eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (rtc_is_hctosys(rtc_id)) { 3430eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGV("found wall clock RTC %u", rtc_id); 3440eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann return rtc_id; 3450eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann } 3460eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann } 3470eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3480eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann if (errno == 0) 3490eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGW("no wall clock RTC found"); 3500eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann else 3510eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann ALOGE("failed to enumerate RTCs: %s", strerror(errno)); 3520eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 3530eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann return -1; 3540eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann} 3550eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann 356a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jlong init_timerfd() 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 358a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int epollfd; 359a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int fds[N_ANDROID_TIMERFDS]; 360a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 361a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epollfd = epoll_create(N_ANDROID_TIMERFDS); 362a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (epollfd < 0) { 36346c82b4cd241a447834ed2f5a6be16777b7a990bBernhard Rosenkränzer ALOGV("epoll_create(%zu) failed: %s", N_ANDROID_TIMERFDS, 364a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann strerror(errno)); 365a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 366a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 367a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 368a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { 369a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann fds[i] = timerfd_create(android_alarm_to_clockid[i], 0); 370a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (fds[i] < 0) { 371a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("timerfd_create(%u) failed: %s", android_alarm_to_clockid[i], 372a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann strerror(errno)); 373a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(epollfd); 374a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t j = 0; j < i; j++) { 375a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(fds[j]); 376a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 377a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 378a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 379a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 380a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 3810eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd, wall_clock_rtc()); 382a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 383a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { 384a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epoll_event event; 385a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann event.events = EPOLLIN | EPOLLWAKEUP; 386a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann event.data.u32 = i; 387a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 388a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event); 389a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (err < 0) { 390a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); 391a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete ret; 392a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 393a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 394a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 395a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 396a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann struct itimerspec spec; 397a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memset(&spec, 0, sizeof(spec)); 398a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann /* 0 = disarmed; the timerfd doesn't need to be armed to get 399a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann RTC change notifications, just set up as cancelable */ 400a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 401a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT], 402a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL); 403a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (err < 0) { 404a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("timerfd_settime() failed: %s", strerror(errno)); 405a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete ret; 406a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 407a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 408a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 409a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return reinterpret_cast<jlong>(ret); 410a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 411a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 412a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) 413a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 414a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann jlong ret = init_alarm_driver(); 415a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (ret) { 416a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return ret; 417a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 418a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 419a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return init_timerfd(); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 422a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic void android_server_AlarmManagerService_close(JNIEnv*, jobject, jlong nativeData) 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 424a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 425a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete impl; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 428a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativeData, jint type, jlong seconds, jlong nanoseconds) 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 430a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timespec ts; 43211c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown ts.tv_sec = seconds; 43311c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown ts.tv_nsec = nanoseconds; 434dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 435a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int result = impl->set(type, &ts); 43632b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann if (result < 0) 43732b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann { 438f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat ALOGE("Unable to set alarm to %lld.%09lld: %s\n", 439f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat static_cast<long long>(seconds), 440f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat static_cast<long long>(nanoseconds), strerror(errno)); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 444a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jlong nativeData) 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 446a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 44732b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann int result = 0; 448dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 44932b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann do 45032b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann { 451a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann result = impl->waitForAlarm(); 45232b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann } while (result < 0 && errno == EINTR); 453dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 45432b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann if (result < 0) 45532b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann { 4563762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Unable to wait on alarm: %s\n", strerror(errno)); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 459dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod sMethods[] = { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 465a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"init", "()J", (void*)android_server_AlarmManagerService_init}, 466a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"close", "(J)V", (void*)android_server_AlarmManagerService_close}, 467a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set}, 468a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm}, 46938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann {"setKernelTime", "(JJ)I", (void*)android_server_AlarmManagerService_setKernelTime}, 470a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_AlarmManagerService(JNIEnv* env) 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService", 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sMethods, NELEM(sMethods)); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */ 480