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>
4038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann#include <linux/rtc.h>
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann#include <array>
43e45abfa083cacdd858feb7c6bcf0b03647a37989Mykola Kondratenko#include <memory>
44e45abfa083cacdd858feb7c6bcf0b03647a37989Mykola Kondratenko
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannstatic constexpr int ANDROID_ALARM_TIME_CHANGE_MASK = 1 << 16;
48d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann
49d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann/**
50d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann * The AlarmManager alarm constants:
51d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *
52d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *   RTC_WAKEUP
53d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *   RTC
54d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *   REALTIME_WAKEUP
55d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *   REALTIME
56d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *   SYSTEMTIME (only defined in old alarm driver header, possibly unused?)
57d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann *
58d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann * We also need an extra CLOCK_REALTIME fd which exists specifically to be
59d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann * canceled on RTC changes.
60d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann */
61d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannstatic const size_t ANDROID_ALARM_TYPE_COUNT = 5;
62a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic const size_t N_ANDROID_TIMERFDS = ANDROID_ALARM_TYPE_COUNT + 1;
63a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = {
64a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    CLOCK_REALTIME_ALARM,
65a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    CLOCK_REALTIME,
66a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    CLOCK_BOOTTIME_ALARM,
67a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    CLOCK_BOOTTIME,
68a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    CLOCK_MONOTONIC,
69a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    CLOCK_REALTIME,
70a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann};
71dea57bac3d08a34ceb531e88e7e59b77d0fdc27cGreg Hackmann
72d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmanntypedef std::array<int, N_ANDROID_TIMERFDS> TimerFds;
73dea57bac3d08a34ceb531e88e7e59b77d0fdc27cGreg Hackmann
74d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannclass AlarmImpl
75dea57bac3d08a34ceb531e88e7e59b77d0fdc27cGreg Hackmann{
76dea57bac3d08a34ceb531e88e7e59b77d0fdc27cGreg Hackmannpublic:
77d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    AlarmImpl(const TimerFds &fds, int epollfd, int rtc_id) :
78d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann        fds{fds}, epollfd{epollfd}, rtc_id{rtc_id} { }
79d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    ~AlarmImpl();
80a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
81a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int set(int type, struct timespec *ts);
8238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    int setTime(struct timeval *tv);
83a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int waitForAlarm();
84a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
85a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannprivate:
86d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    const TimerFds fds;
87d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    const int epollfd;
88d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    const int rtc_id;
89a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann};
90a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
91a1d6f92f34adb499565c9513235227a308e90221Greg HackmannAlarmImpl::~AlarmImpl()
92a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{
93d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    for (auto fd : fds) {
94d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann        epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, nullptr);
95d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann        close(fd);
96a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
97dea57bac3d08a34ceb531e88e7e59b77d0fdc27cGreg Hackmann
98a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    close(epollfd);
99a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}
100a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
101d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannint AlarmImpl::set(int type, struct timespec *ts)
102a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{
103d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    if (static_cast<size_t>(type) > ANDROID_ALARM_TYPE_COUNT) {
104a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        errno = EINVAL;
105a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        return -1;
106a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
107a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
108a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    if (!ts->tv_nsec && !ts->tv_sec) {
109a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        ts->tv_nsec = 1;
110a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
111a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    /* timerfd interprets 0 = disarm, so replace with a practically
112a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann       equivalent deadline of 1 ns */
113a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
114a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    struct itimerspec spec;
115a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    memset(&spec, 0, sizeof(spec));
116a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    memcpy(&spec.it_value, ts, sizeof(spec.it_value));
117a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
118a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL);
119a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}
120a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
121d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannint AlarmImpl::setTime(struct timeval *tv)
12238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann{
12338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    struct rtc_time rtc;
12438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    struct tm tm, *gmtime_res;
12538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    int fd;
12638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    int res;
12738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
12838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    res = settimeofday(tv, NULL);
12938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    if (res < 0) {
13038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        ALOGV("settimeofday() failed: %s\n", strerror(errno));
131c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann        return -1;
132c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann    }
133c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann
1340eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    if (rtc_id < 0) {
1350eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGV("Not setting RTC because wall clock RTC was not found");
1360eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        errno = ENODEV;
1370eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        return -1;
1380eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    }
1390eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
1400eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    android::String8 rtc_dev = String8::format("/dev/rtc%d", rtc_id);
1410eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    fd = open(rtc_dev.string(), O_RDWR);
142c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann    if (fd < 0) {
1430eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGV("Unable to open %s: %s\n", rtc_dev.string(), strerror(errno));
144c9244720da829cac94918555761468ebdd2b7c5dGreg Hackmann        return res;
14538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    }
14638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
14738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    gmtime_res = gmtime_r(&tv->tv_sec, &tm);
14838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    if (!gmtime_res) {
14938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        ALOGV("gmtime_r() failed: %s\n", strerror(errno));
15038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        res = -1;
15138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        goto done;
15238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    }
15338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
15438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    memset(&rtc, 0, sizeof(rtc));
15538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_sec = tm.tm_sec;
15638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_min = tm.tm_min;
15738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_hour = tm.tm_hour;
15838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_mday = tm.tm_mday;
15938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_mon = tm.tm_mon;
16038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_year = tm.tm_year;
16138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_wday = tm.tm_wday;
16238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_yday = tm.tm_yday;
16338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    rtc.tm_isdst = tm.tm_isdst;
16438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    res = ioctl(fd, RTC_SET_TIME, &rtc);
16538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    if (res < 0)
16638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        ALOGV("RTC_SET_TIME ioctl failed: %s\n", strerror(errno));
16738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmanndone:
16838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    close(fd);
16938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    return res;
17038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann}
17138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
172d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannint AlarmImpl::waitForAlarm()
173a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann{
174a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    epoll_event events[N_ANDROID_TIMERFDS];
175a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
176a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int nevents = epoll_wait(epollfd, events, N_ANDROID_TIMERFDS, -1);
177a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    if (nevents < 0) {
178a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        return nevents;
179a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
180a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
181a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int result = 0;
182a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    for (int i = 0; i < nevents; i++) {
183a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        uint32_t alarm_idx = events[i].data.u32;
184a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        uint64_t unused;
185a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        ssize_t err = read(fds[alarm_idx], &unused, sizeof(unused));
186a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        if (err < 0) {
187a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            if (alarm_idx == ANDROID_ALARM_TYPE_COUNT && errno == ECANCELED) {
188a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann                result |= ANDROID_ALARM_TIME_CHANGE_MASK;
189a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            } else {
190a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann                return err;
191a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            }
192a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        } else {
193a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            result |= (1 << alarm_idx);
194a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        }
195a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
196a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
197a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    return result;
198a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}
199a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
20038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmannstatic jint android_server_AlarmManagerService_setKernelTime(JNIEnv*, jobject, jlong nativeData, jlong millis)
20138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann{
20238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
20338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    struct timeval tv;
20438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    int ret;
20538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
20638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    if (millis <= 0 || millis / 1000LL >= INT_MAX) {
20738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        return -1;
20838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    }
20938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
21038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    tv.tv_sec = (time_t) (millis / 1000LL);
21138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
21238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
21338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
21438bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
21538bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    ret = impl->setTime(&tv);
21638bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
21738bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    if(ret < 0) {
21838bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
21938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann        ret = -1;
22038bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    }
22138bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    return ret;
22238bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann}
22338bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann
224a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobject, jlong, jint minswest)
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct timezone tz;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    tz.tz_minuteswest = minswest;
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    tz.tz_dsttime = 0;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = settimeofday(NULL, &tz);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (result < 0) {
2333762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Unable to set kernel timezone to %d: %s\n", minswest, strerror(errno));
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
2365baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Kernel timezone updated to %d minutes west of GMT\n", minswest);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2420eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmannstatic const char rtc_sysfs[] = "/sys/class/rtc";
2430eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2440eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmannstatic bool rtc_is_hctosys(unsigned int rtc_id)
2450eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann{
2460eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    android::String8 hctosys_path = String8::format("%s/rtc%u/hctosys",
2470eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann            rtc_sysfs, rtc_id);
2480eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    FILE *file = fopen(hctosys_path.string(), "re");
2490eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    if (!file) {
2500eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGE("failed to open %s: %s", hctosys_path.string(), strerror(errno));
2510eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        return false;
2520eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    }
2530eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2540eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    unsigned int hctosys;
2550eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    bool ret = false;
2560eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    int err = fscanf(file, "%u", &hctosys);
2570eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    if (err == EOF)
2580eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGE("failed to read from %s: %s", hctosys_path.string(),
2590eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann                strerror(errno));
2600eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    else if (err == 0)
2610eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGE("%s did not have expected contents", hctosys_path.string());
2620eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    else
2630eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ret = hctosys;
2640eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2650eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    fclose(file);
2660eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    return ret;
2670eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann}
2680eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2690eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmannstatic int wall_clock_rtc()
2700eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann{
271e45abfa083cacdd858feb7c6bcf0b03647a37989Mykola Kondratenko    std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(rtc_sysfs), closedir);
272e45abfa083cacdd858feb7c6bcf0b03647a37989Mykola Kondratenko    if (!dir.get()) {
2730eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGE("failed to open %s: %s", rtc_sysfs, strerror(errno));
2740eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        return -1;
2750eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    }
2760eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2770eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    struct dirent *dirent;
278e45abfa083cacdd858feb7c6bcf0b03647a37989Mykola Kondratenko    while (errno = 0, dirent = readdir(dir.get())) {
2790eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        unsigned int rtc_id;
2800eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id);
2810eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2820eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        if (matched < 0)
2830eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann            break;
2840eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        else if (matched != 1)
2850eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann            continue;
2860eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2870eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        if (rtc_is_hctosys(rtc_id)) {
2880eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann            ALOGV("found wall clock RTC %u", rtc_id);
2890eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann            return rtc_id;
2900eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        }
2910eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    }
2920eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2930eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    if (errno == 0)
2940eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGW("no wall clock RTC found");
2950eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    else
2960eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann        ALOGE("failed to enumerate RTCs: %s", strerror(errno));
2970eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
2980eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann    return -1;
2990eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann}
3000eb5826830592695f4a5b4d1dba18e0ca991163eGreg Hackmann
301a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmannstatic void log_timerfd_create_error(clockid_t id)
302a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann{
303a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann    if (errno == EINVAL) {
304a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann        switch (id) {
305a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann        case CLOCK_REALTIME_ALARM:
306a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann        case CLOCK_BOOTTIME_ALARM:
307a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            ALOGE("kernel missing required commits:");
308a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6cffe00f7d4e24679eae6b7aae4caaf915288256");
309a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=11ffa9d6065f344a9bd769a2452f26f2f671e5f8");
310a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            LOG_ALWAYS_FATAL("kernel does not support timerfd_create() with alarm timers");
311a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            break;
312a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann
313a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann        case CLOCK_BOOTTIME:
314a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            ALOGE("kernel missing required commit:");
315a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4a2378a943f09907fb1ae35c15de917f60289c14");
316a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            LOG_ALWAYS_FATAL("kernel does not support timerfd_create(CLOCK_BOOTTIME)");
317a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            break;
318a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann
319a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann        default:
320a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            break;
321a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann        }
322a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann    }
323a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann
324a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann    ALOGE("timerfd_create(%u) failed: %s", id, strerror(errno));
325a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann}
326a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann
327d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmannstatic jlong android_server_AlarmManagerService_init(JNIEnv*, jobject)
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
329a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int epollfd;
330d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    TimerFds fds;
331a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
332d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    epollfd = epoll_create(fds.size());
333a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    if (epollfd < 0) {
334d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann        ALOGE("epoll_create(%zu) failed: %s", fds.size(),
335a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann                strerror(errno));
336a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        return 0;
337a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
338a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
339d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    for (size_t i = 0; i < fds.size(); i++) {
340a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        fds[i] = timerfd_create(android_alarm_to_clockid[i], 0);
341a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        if (fds[i] < 0) {
342a0126e0857481866dab5060384d611c83ca53d0eGreg Hackmann            log_timerfd_create_error(android_alarm_to_clockid[i]);
343a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            close(epollfd);
344a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            for (size_t j = 0; j < i; j++) {
345a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann                close(fds[j]);
346a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            }
347a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            return 0;
348a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        }
349a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
350a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
351d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    AlarmImpl *ret = new AlarmImpl(fds, epollfd, wall_clock_rtc());
352a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
353d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann    for (size_t i = 0; i < fds.size(); i++) {
354a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        epoll_event event;
355a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        event.events = EPOLLIN | EPOLLWAKEUP;
356a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        event.data.u32 = i;
357a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
358a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event);
359a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        if (err < 0) {
360d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann            ALOGE("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno));
361a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            delete ret;
362a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            return 0;
363a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        }
364a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
365a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
366a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    struct itimerspec spec;
367a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    memset(&spec, 0, sizeof(spec));
368a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    /* 0 = disarmed; the timerfd doesn't need to be armed to get
369a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann       RTC change notifications, just set up as cancelable */
370a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
371a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT],
372a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann            TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL);
373a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    if (err < 0) {
374d7151c06f11c05ad3dcab175a6e4b4ea694dab96Greg Hackmann        ALOGE("timerfd_settime() failed: %s", strerror(errno));
375a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        delete ret;
376a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        return 0;
377a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    }
378a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
379a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    return reinterpret_cast<jlong>(ret);
380a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann}
381a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann
382a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic void android_server_AlarmManagerService_close(JNIEnv*, jobject, jlong nativeData)
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
384a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
385a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    delete impl;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
388a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativeData, jint type, jlong seconds, jlong nanoseconds)
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
390a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct timespec ts;
39211c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown    ts.tv_sec = seconds;
39311c5f1a65d6c495cc60f9f15d408c776baed9f73Jeff Brown    ts.tv_nsec = nanoseconds;
394dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes
395a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    int result = impl->set(type, &ts);
39632b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    if (result < 0)
39732b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    {
398f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        ALOGE("Unable to set alarm to %lld.%09lld: %s\n",
399f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat              static_cast<long long>(seconds),
400f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat              static_cast<long long>(nanoseconds), strerror(errno));
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
404a1d6f92f34adb499565c9513235227a308e90221Greg Hackmannstatic jint android_server_AlarmManagerService_waitForAlarm(JNIEnv*, jobject, jlong nativeData)
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
406a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
40732b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    int result = 0;
408dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes
40932b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    do
41032b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    {
411a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann        result = impl->waitForAlarm();
41232b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    } while (result < 0 && errno == EINTR);
413dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes
41432b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    if (result < 0)
41532b4c0779ea3a0149b31a1340513e9e0a6897b5fGreg Hackmann    {
4163762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Unable to wait on alarm: %s\n", strerror(errno));
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
419dd66bcbf9d6ef0c50a18d9c4b1b39ce7ef7afcc4Elliott Hughes
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
42376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod sMethods[] = {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     /* name, signature, funcPtr */
425a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    {"init", "()J", (void*)android_server_AlarmManagerService_init},
426a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    {"close", "(J)V", (void*)android_server_AlarmManagerService_close},
427a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    {"set", "(JIJJ)V", (void*)android_server_AlarmManagerService_set},
428a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    {"waitForAlarm", "(J)I", (void*)android_server_AlarmManagerService_waitForAlarm},
42938bf51466881b726f42832743d8cca6ee67bb148Greg Hackmann    {"setKernelTime", "(JJ)I", (void*)android_server_AlarmManagerService_setKernelTime},
430a1d6f92f34adb499565c9513235227a308e90221Greg Hackmann    {"setKernelTimezone", "(JI)I", (void*)android_server_AlarmManagerService_setKernelTimezone},
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_server_AlarmManagerService(JNIEnv* env)
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return jniRegisterNativeMethods(env, "com/android/server/AlarmManagerService",
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    sMethods, NELEM(sMethods));
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} /* namespace android */
440