diff options
| author | Mister Oyster <oysterized@gmail.com> | 2018-01-07 14:25:22 +0100 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2018-01-07 14:25:22 +0100 |
| commit | d2be7057fdb22fefa828fba948dc02c7bffccfe1 (patch) | |
| tree | a0522159c2812e370a905cab56b941ef8f7ea97d | |
| parent | 6470d7e9300829516b6fbe155082cc9ff11bf867 (diff) | |
patch: fix dev-alarm support
| -rw-r--r-- | patches/frameworks/base/0002-mtk-bring-back-legacy-dev-alarm-support.patch | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/patches/frameworks/base/0002-mtk-bring-back-legacy-dev-alarm-support.patch b/patches/frameworks/base/0002-mtk-bring-back-legacy-dev-alarm-support.patch new file mode 100644 index 0000000..b9d6e31 --- /dev/null +++ b/patches/frameworks/base/0002-mtk-bring-back-legacy-dev-alarm-support.patch @@ -0,0 +1,312 @@ +From b51abbffc027dee8baa7c5552fc3b20407477275 Mon Sep 17 00:00:00 2001 +From: Mister Oyster <oysterized@gmail.com> +Date: Sun, 7 Jan 2018 14:22:52 +0100 +Subject: [PATCH] mtk: bring back legacy /dev/alarm support + +Revert "AlarmManagerService: explain some timerfd_create() failures" +This reverts commit a0126e0857481866dab5060384d611c83ca53d0e. + +Revert "AlarmManagerService: remove legacy /dev/alarm support" +This reverts commit d7151c06f11c05ad3dcab175a6e4b4ea694dab96. + +Revert "Remove dependency on android_alarm.h." +This reverts commit 338893e47ed8e2a913e5def987469647809cdbc6. +--- + .../jni/com_android_server_AlarmManagerService.cpp | 176 +++++++++++++-------- + 1 file changed, 109 insertions(+), 67 deletions(-) + +diff --git a/services/core/jni/com_android_server_AlarmManagerService.cpp b/services/core/jni/com_android_server_AlarmManagerService.cpp +index 3a0273d8c3c..407c0726e52 100644 +--- a/services/core/jni/com_android_server_AlarmManagerService.cpp ++++ b/services/core/jni/com_android_server_AlarmManagerService.cpp +@@ -37,28 +37,13 @@ + #include <errno.h> + #include <unistd.h> + #include <linux/ioctl.h> ++#include <linux/android_alarm.h> + #include <linux/rtc.h> + +-#include <array> + #include <memory> + + namespace android { + +-static constexpr int ANDROID_ALARM_TIME_CHANGE_MASK = 1 << 16; +- +-/** +- * The AlarmManager alarm constants: +- * +- * RTC_WAKEUP +- * RTC +- * REALTIME_WAKEUP +- * REALTIME +- * SYSTEMTIME (only defined in old alarm driver header, possibly unused?) +- * +- * We also need an extra CLOCK_REALTIME fd which exists specifically to be +- * canceled on RTC changes. +- */ +-static const size_t ANDROID_ALARM_TYPE_COUNT = 5; + static const size_t N_ANDROID_TIMERFDS = ANDROID_ALARM_TYPE_COUNT + 1; + static const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = { + CLOCK_REALTIME_ALARM, +@@ -68,39 +53,98 @@ static const clockid_t android_alarm_to_clockid[N_ANDROID_TIMERFDS] = { + CLOCK_MONOTONIC, + CLOCK_REALTIME, + }; +- +-typedef std::array<int, N_ANDROID_TIMERFDS> TimerFds; ++/* to match the legacy alarm driver implementation, we need an extra ++ CLOCK_REALTIME fd which exists specifically to be canceled on RTC changes */ + + class AlarmImpl + { + public: +- AlarmImpl(const TimerFds &fds, int epollfd, int rtc_id) : +- fds{fds}, epollfd{epollfd}, rtc_id{rtc_id} { } +- ~AlarmImpl(); ++ AlarmImpl(int *fds, size_t n_fds); ++ virtual ~AlarmImpl(); ++ ++ virtual int set(int type, struct timespec *ts) = 0; ++ virtual int setTime(struct timeval *tv) = 0; ++ virtual int waitForAlarm() = 0; ++ ++protected: ++ int *fds; ++ size_t n_fds; ++}; ++ ++class AlarmImplAlarmDriver : public AlarmImpl ++{ ++public: ++ explicit AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { } ++ ++ int set(int type, struct timespec *ts); ++ int setTime(struct timeval *tv); ++ int waitForAlarm(); ++}; ++ ++class AlarmImplTimerFd : public AlarmImpl ++{ ++public: ++ AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd, int rtc_id) : ++ AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd), rtc_id(rtc_id) { } ++ ~AlarmImplTimerFd(); + + int set(int type, struct timespec *ts); + int setTime(struct timeval *tv); + int waitForAlarm(); + + private: +- const TimerFds fds; +- const int epollfd; +- const int rtc_id; ++ int epollfd; ++ int rtc_id; + }; + ++AlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]), ++ n_fds(n_fds) ++{ ++ memcpy(fds, fds_, n_fds * sizeof(fds[0])); ++} ++ + AlarmImpl::~AlarmImpl() + { +- for (auto fd : fds) { +- epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, nullptr); +- close(fd); ++ for (size_t i = 0; i < n_fds; i++) { ++ close(fds[i]); + } ++ delete [] fds; ++} ++ ++int AlarmImplAlarmDriver::set(int type, struct timespec *ts) ++{ ++ return ioctl(fds[0], ANDROID_ALARM_SET(type), ts); ++} ++ ++int AlarmImplAlarmDriver::setTime(struct timeval *tv) ++{ ++ struct timespec ts; ++ int res; ++ ++ ts.tv_sec = tv->tv_sec; ++ ts.tv_nsec = tv->tv_usec * 1000; ++ res = ioctl(fds[0], ANDROID_ALARM_SET_RTC, &ts); ++ if (res < 0) ++ ALOGV("ANDROID_ALARM_SET_RTC ioctl failed: %s\n", strerror(errno)); ++ return res; ++} + ++int AlarmImplAlarmDriver::waitForAlarm() ++{ ++ return ioctl(fds[0], ANDROID_ALARM_WAIT); ++} ++ ++AlarmImplTimerFd::~AlarmImplTimerFd() ++{ ++ for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { ++ epoll_ctl(epollfd, EPOLL_CTL_DEL, fds[i], NULL); ++ } + close(epollfd); + } + +-int AlarmImpl::set(int type, struct timespec *ts) ++int AlarmImplTimerFd::set(int type, struct timespec *ts) + { +- if (static_cast<size_t>(type) > ANDROID_ALARM_TYPE_COUNT) { ++ if (type > ANDROID_ALARM_TYPE_COUNT) { + errno = EINVAL; + return -1; + } +@@ -118,7 +162,7 @@ int AlarmImpl::set(int type, struct timespec *ts) + return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL); + } + +-int AlarmImpl::setTime(struct timeval *tv) ++int AlarmImplTimerFd::setTime(struct timeval *tv) + { + struct rtc_time rtc; + struct tm tm, *gmtime_res; +@@ -169,7 +213,7 @@ done: + return res; + } + +-int AlarmImpl::waitForAlarm() ++int AlarmImplTimerFd::waitForAlarm() + { + epoll_event events[N_ANDROID_TIMERFDS]; + +@@ -239,12 +283,25 @@ static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv*, jobjec + return 0; + } + ++static jlong init_alarm_driver() ++{ ++ int fd = open("/dev/alarm", O_RDWR); ++ if (fd < 0) { ++ ALOGV("opening alarm driver failed: %s", strerror(errno)); ++ return 0; ++ } ++ ++ AlarmImpl *ret = new AlarmImplAlarmDriver(fd); ++ return reinterpret_cast<jlong>(ret); ++} ++ + static const char rtc_sysfs[] = "/sys/class/rtc"; + + static bool rtc_is_hctosys(unsigned int rtc_id) + { + android::String8 hctosys_path = String8::format("%s/rtc%u/hctosys", + rtc_sysfs, rtc_id); ++ + FILE *file = fopen(hctosys_path.string(), "re"); + if (!file) { + ALOGE("failed to open %s: %s", hctosys_path.string(), strerror(errno)); +@@ -298,48 +355,23 @@ static int wall_clock_rtc() + return -1; + } + +-static void log_timerfd_create_error(clockid_t id) +-{ +- if (errno == EINVAL) { +- switch (id) { +- case CLOCK_REALTIME_ALARM: +- case CLOCK_BOOTTIME_ALARM: +- ALOGE("kernel missing required commits:"); +- ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6cffe00f7d4e24679eae6b7aae4caaf915288256"); +- ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=11ffa9d6065f344a9bd769a2452f26f2f671e5f8"); +- LOG_ALWAYS_FATAL("kernel does not support timerfd_create() with alarm timers"); +- break; +- +- case CLOCK_BOOTTIME: +- ALOGE("kernel missing required commit:"); +- ALOGE("https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4a2378a943f09907fb1ae35c15de917f60289c14"); +- LOG_ALWAYS_FATAL("kernel does not support timerfd_create(CLOCK_BOOTTIME)"); +- break; +- +- default: +- break; +- } +- } +- +- ALOGE("timerfd_create(%u) failed: %s", id, strerror(errno)); +-} +- +-static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) ++static jlong init_timerfd() + { + int epollfd; +- TimerFds fds; ++ int fds[N_ANDROID_TIMERFDS]; + +- epollfd = epoll_create(fds.size()); ++ epollfd = epoll_create(N_ANDROID_TIMERFDS); + if (epollfd < 0) { +- ALOGE("epoll_create(%zu) failed: %s", fds.size(), ++ ALOGV("epoll_create(%zu) failed: %s", N_ANDROID_TIMERFDS, + strerror(errno)); + return 0; + } + +- for (size_t i = 0; i < fds.size(); i++) { ++ for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { + fds[i] = timerfd_create(android_alarm_to_clockid[i], 0); + if (fds[i] < 0) { +- log_timerfd_create_error(android_alarm_to_clockid[i]); ++ ALOGV("timerfd_create(%u) failed: %s", android_alarm_to_clockid[i], ++ strerror(errno)); + close(epollfd); + for (size_t j = 0; j < i; j++) { + close(fds[j]); +@@ -348,16 +380,16 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) + } + } + +- AlarmImpl *ret = new AlarmImpl(fds, epollfd, wall_clock_rtc()); ++ AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd, wall_clock_rtc()); + +- for (size_t i = 0; i < fds.size(); i++) { ++ for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) { + epoll_event event; + event.events = EPOLLIN | EPOLLWAKEUP; + event.data.u32 = i; + + int err = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], &event); + if (err < 0) { +- ALOGE("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); ++ ALOGV("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno)); + delete ret; + return 0; + } +@@ -371,7 +403,7 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) + int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT], + TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL); + if (err < 0) { +- ALOGE("timerfd_settime() failed: %s", strerror(errno)); ++ ALOGV("timerfd_settime() failed: %s", strerror(errno)); + delete ret; + return 0; + } +@@ -379,6 +411,16 @@ static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) + return reinterpret_cast<jlong>(ret); + } + ++static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject) ++{ ++ jlong ret = init_alarm_driver(); ++ if (ret) { ++ return ret; ++ } ++ ++ return init_timerfd(); ++} ++ + static void android_server_AlarmManagerService_close(JNIEnv*, jobject, jlong nativeData) + { + AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData); +-- +2.14.1 + |
