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