com_android_server_AlarmManagerService.cpp revision a1d6f92f34adb499565c9513235227a308e90221
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> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 28a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann#include <sys/epoll.h> 29a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann#include <sys/timerfd.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/socket.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <arpa/inet.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/in.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/ioctl.h> 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/android_alarm.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic const size_t N_ANDROID_TIMERFDS = ANDROID_ALARM_TYPE_COUNT + 1; 43a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = { 44a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME_ALARM, 45a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME, 46a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_BOOTTIME_ALARM, 47a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_BOOTTIME, 48a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_MONOTONIC, 49a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME, 50a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 51a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann/* to match the legacy alarm driver implementation, we need an extra 52a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann CLOCK_REALTIME fd which exists specifically to be canceled on RTC changes */ 53a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 54a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannclass AlarmImpl 55a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 56a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannpublic: 57a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl(int *fds, size_t n_fds); 58a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann virtual ~AlarmImpl(); 59a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 60a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann virtual int set(int type, struct timespec *ts) = 0; 61a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann virtual int waitForAlarm() = 0; 62a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 63a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannprotected: 64a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int *fds; 65a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann size_t n_fds; 66a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 67a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 68a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannclass AlarmImplAlarmDriver : public AlarmImpl 69a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 70a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannpublic: 71a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { } 72a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 73a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int set(int type, struct timespec *ts); 74a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int waitForAlarm(); 75a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 76a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 77a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannclass AlarmImplTimerFd : public AlarmImpl 78a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 79a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannpublic: 80a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd) : 81a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd) { } 82a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ~AlarmImplTimerFd(); 83a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 84a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int set(int type, struct timespec *ts); 85a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int waitForAlarm(); 86a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 87a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannprivate: 88a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int epollfd; 89a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}; 90a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 91a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]), 92a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann n_fds(n_fds) 93a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 94a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memcpy(fds, fds_, n_fds * sizeof(fds[0])); 95a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 96a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 97a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImpl::~AlarmImpl() 98a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 99a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < n_fds; i++) { 100a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(fds[i]); 101a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 102a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete [] fds; 103a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 104a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 105a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplAlarmDriver::set(int type, struct timespec *ts) 106a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 107a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return ioctl(fds[0], ANDROID_ALARM_SET(type), ts); 108a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 109a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 110a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplAlarmDriver::waitForAlarm() 111a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 112a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return ioctl(fds[0], ANDROID_ALARM_WAIT); 113a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 114a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 115a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImplTimerFd::~AlarmImplTimerFd() 116a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 117a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { 118a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epoll_ctl(epollfd, EPOLL_CTL_DEL, fds[i], NULL); 119a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 120a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(epollfd); 121a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 122a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 123a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplTimerFd::set(int type, struct timespec *ts) 124a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 125a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (type > ANDROID_ALARM_TYPE_COUNT) { 126a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann errno = EINVAL; 127a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return -1; 128a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 129a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 130a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (!ts->tv_nsec && !ts->tv_sec) { 131a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ts->tv_nsec = 1; 132a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 133a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann /* timerfd interprets 0 = disarm, so replace with a practically 134a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann equivalent deadline of 1 ns */ 135a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 136a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann struct itimerspec spec; 137a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memset(&spec, 0, sizeof(spec)); 138a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memcpy(&spec.it_value, ts, sizeof(spec.it_value)); 139a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 140a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL); 141a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 142a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 143a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannint AlarmImplTimerFd::waitForAlarm() 144a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 145a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epoll_event events[N_ANDROID_TIMERFDS]; 146a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 147a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int nevents = epoll_wait(epollfd, events, N_ANDROID_TIMERFDS, -1); 148a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (nevents < 0) { 149a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return nevents; 150a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 151a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 152a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int result = 0; 153a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (int i = 0; i < nevents; i++) { 154a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann uint32_t alarm_idx = events[i].data.u32; 155a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann uint64_t unused; 156a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ssize_t err = read(fds[alarm_idx], &unused, sizeof(unused)); 157a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (err < 0) { 158a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (alarm_idx == ANDROID_ALARM_TYPE_COUNT && errno == ECANCELED) { 159a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann result |= ANDROID_ALARM_TIME_CHANGE_MASK; 160a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } else { 161a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return err; 162a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 163a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } else { 164a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann result |= (1 << alarm_idx); 165a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 166a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 167a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 168a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return result; 169a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 170a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 171a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest) 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timezone tz; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tz.tz_minuteswest = minswest; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tz.tz_dsttime = 0; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = settimeofday(NULL, &tz); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result < 0) { 1803762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno)); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jlong init_alarm_driver() 190a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 191a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int fd = open("/dev/alarm", O_RDWR); 192a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (fd < 0) { 193a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("opening alarm driver failed: %s", strerror(errno)); 194a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 195a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 196a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 197a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *ret = new AlarmImplAlarmDriver(fd); 198a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return reinterpret_cast<jlong>(ret); 199a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 200a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 201a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jlong init_timerfd() 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 203a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int epollfd; 204a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int fds[N_ANDROID_TIMERFDS]; 205a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 206a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epollfd = epoll_create(N_ANDROID_TIMERFDS); 207a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (epollfd < 0) { 208a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("epoll_create(%u) failed: %s", N_ANDROID_TIMERFDS, 209a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann strerror(errno)); 210a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 211a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 212a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 213a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { 214a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann fds[i] = timerfd_create(android_alarm_to_clockid[i], 0); 215a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (fds[i] < 0) { 216a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("timerfd_create(%u) failed: %s", android_alarm_to_clockid[i], 217a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann strerror(errno)); 218a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(epollfd); 219a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t j = 0; j < i; j++) { 220a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann close(fds[j]); 221a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 222a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 223a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 224a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 225a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 226a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd); 227a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 228a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { 229a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann epoll_event event; 230a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann event.events = EPOLLIN | EPOLLWAKEUP; 231a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann event.data.u32 = i; 232a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 233a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event); 234a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (err < 0) { 235a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); 236a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete ret; 237a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 238a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 239a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 240a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 241a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann struct itimerspec spec; 242a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann memset(&spec, 0, sizeof(spec)); 243a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann /* 0 = disarmed; the timerfd doesn't need to be armed to get 244a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann RTC change notifications, just set up as cancelable */ 245a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 246a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT], 247a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL); 248a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (err < 0) { 249a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann ALOGV("timerfd_settime() failed: %s", strerror(errno)); 250a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete ret; 251a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return 0; 252a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 253a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 254a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return reinterpret_cast<jlong>(ret); 255a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann} 256a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 257a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) 258a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{ 259a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann jlong ret = init_alarm_driver(); 260a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann if (ret) { 261a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return ret; 262a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann } 263a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann 264a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann return init_timerfd(); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 267a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic void android_server_AlarmManagerService_close(JNIEnv*, jobject, jlong nativeData) 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 269a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 270a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann delete impl; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 273a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativeData, jint type, jlong seconds, jlong nanoseconds) 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 275a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct timespec ts; 27711c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown ts.tv_sec = seconds; 27811c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown ts.tv_nsec = nanoseconds; 279dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 280a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann int result = impl->set(type, &ts); 28132b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann if (result < 0) 28232b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann { 2833762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno)); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 287a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jlong nativeData) 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 289a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); 29032b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann int result = 0; 291dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 29232b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann do 29332b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann { 294a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann result = impl->waitForAlarm(); 29532b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann } while (result < 0 && errno == EINTR); 296dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 29732b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann if (result < 0) 29832b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann { 2993762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Unable to wait on alarm: %s\n", strerror(errno)); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 302dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod sMethods[] = { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 308a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"init", "()J", (void*)android_server_AlarmManagerService_init}, 309a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"close", "(J)V", (void*)android_server_AlarmManagerService_close}, 310a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set}, 311a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm}, 312a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann {"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone}, 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_AlarmManagerService(JNIEnv* env) 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService", 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sMethods, NELEM(sMethods)); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */ 322