您的位置:首页 > 其它

AlarmManagerService的hal层分析

2016-06-12 17:07 288 查看
之前我们分析过AlarmManagerService了,这里我们主要分析下其hal层。

我们先来看onStart这段代码:

public void onStart() {
mNativeData = init();

这个init函数是native函数,是用来初始化hal层的。mNativeData数据就是从hal层函数返回。

一、有alarm设备

我们看下android_server_AlarmManagerService_init函数,它先调用了init_alarm_driver函数,只要返回不为0,函数就返回。

static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject)
{
jlong ret = init_alarm_driver();
if (ret) {
return ret;
}

return init_timerfd();
}

我们先来看init_alarm_driver函数

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);
}

只要设备支持alarm,就是有dev/alarm这个目录,那我们就把这个fd传入AlarmImplAlarmDriver,然后返回AlarmImplAlarmDriver的对象指针。

我们再来看AlarmManagerService在setLocked中调用set这个native函数,就是设置alarm。

private void setLocked(int type, long when) {
if (mNativeData != 0) {
// The kernel never triggers alarms with negative wakeup times
// so we ensure they are positive.
long alarmSeconds, alarmNanoseconds;
if (when < 0) {
alarmSeconds = 0;
alarmNanoseconds = 0;
} else {
alarmSeconds = when / 1000;
alarmNanoseconds = (when % 1000) * 1000 * 1000;
}

set(mNativeData, type, alarmSeconds, alarmNanoseconds);
}就是把之前的mNativeData的数据传下来,然后调用器set函数。
static void android_server_AlarmManagerService_set(JNIEnv*, jobject, jlong nativeData, jint type, jlong seconds, jlong nanoseconds)
{
AlarmImpl *impl = reinterpret_cast<AlarmImpl *>(nativeData);
struct timespec ts;
ts.tv_sec = seconds;
ts.tv_nsec = nanoseconds;

int result = impl->set(type, &ts);
if (result < 0)
{
ALOGE("Unable to set alarm to %lld.%09lld: %s\n",
static_cast<long long>(seconds),
static_cast<long long>(nanoseconds), strerror(errno));
}
}之前的mNativeData就是下面这个类的对象
class AlarmImplAlarmDriver : public AlarmImpl
{
public:
AlarmImplAlarmDriver(int fd) : AlarmImpl(&fd, 1) { }

int set(int type, struct timespec *ts);
int setTime(struct timeval *tv);
int waitForAlarm();
};最后设置alarm,是调用了ioctl。
int AlarmImplAlarmDriver::set(int type, struct timespec *ts)
{
return ioctl(fds[0], ANDROID_ALARM_SET(type), ts);
}

waitForAlarm函数也是调用ioctl

int AlarmImplAlarmDriver::waitForAlarm()
{
return ioctl(fds[0], ANDROID_ALARM_WAIT);
}



二、没有alarm设备

我们再来看看,假如不支持alarm,hal层又会怎么处理

static jlong android_server_AlarmManagerService_init(JNIEnv*, jobject)
{
jlong ret = init_alarm_driver();
if (ret) {
return ret;
}

return init_timerfd();
}

在调用init函数的时候,如果不支持alarm,就会调用init_timerfd函数:

static jlong init_timerfd()
{
int epollfd;
int fds[N_ANDROID_TIMERFDS];

epollfd = epoll_create(N_ANDROID_TIMERFDS);//epoll
if (epollfd < 0) {
ALOGV("epoll_create(%zu) failed: %s", N_ANDROID_TIMERFDS,
strerror(errno));
return 0;
}

for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) {
fds[i] = timerfd_create(android_alarm_to_clockid[i], 0);//创建定时器
if (fds[i] < 0) {
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]);
}
return 0;
}
}

AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd, wall_clock_rtc());//构造AlarmImplTimerFd对象

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);//把各个定时器fd加入epoll
if (err < 0) {
ALOGV("epoll_ctl(EPOLL_CTL_ADD) failed: %s", strerror(errno));
delete ret;
return 0;
}
}

struct itimerspec spec;
memset(&spec, 0, sizeof(spec));
/* 0 = disarmed; the timerfd doesn't need to be armed to get
RTC change notifications, just set up as cancelable */

int err = timerfd_settime(fds[ANDROID_ALARM_TYPE_COUNT],
TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, NULL);
if (err < 0) {
ALOGV("timerfd_settime() failed: %s", strerror(errno));
delete ret;
return 0;
}

return reinterpret_cast<jlong>(ret);
}

这个函数,主要创建了几个定时器,然后将定时器fd加入epoll。并且mNativeData返回的是AlarmImplTimerFd对象

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:
int epollfd;
int rtc_id;
};

我们来看set函数,这个函数就是调用了定时器的设置时间。

int AlarmImplTimerFd::set(int type, struct timespec *ts)
{
if (type > ANDROID_ALARM_TYPE_COUNT) {
errno = EINVAL;
return -1;
}

if (!ts->tv_nsec && !ts->tv_sec) {
ts->tv_nsec = 1;
}
/* timerfd interprets 0 = disarm, so replace with a practically
equivalent deadline of 1 ns */

struct itimerspec spec;
memset(&spec, 0, sizeof(spec));
memcpy(&spec.it_value, ts, sizeof(spec.it_value));

return timerfd_settime(fds[type], TFD_TIMER_ABSTIME, &spec, NULL);
}

最后我们会在waitForAlarm函数中,使用epoll_wait,当定时器超时就有事件。

int AlarmImplTimerFd::waitForAlarm()
{
epoll_event events[N_ANDROID_TIMERFDS];

int nevents = epoll_wait(epollfd, events, N_ANDROID_TIMERFDS, -1);
if (nevents < 0) {
return nevents;
}

int result = 0;
for (int i = 0; i < nevents; i++) {
uint32_t alarm_idx = events[i].data.u32;
uint64_t unused;
ssize_t err = read(fds[alarm_idx], &unused, sizeof(unused));
if (err < 0) {
if (alarm_idx == ANDROID_ALARM_TYPE_COUNT && errno == ECANCELED) {
result |= ANDROID_ALARM_TIME_CHANGE_MASK;
} else {
return err;
}
} else {
result |= (1 << alarm_idx);
}
}

return result;
}



三、总结

AlarmManagerService的hal层既考虑的支持alarm和不支持alarm,当支持alarm的时候,就是调用ioctl。不支持就是创建定时器,并且将fd加入到epoll机制。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: