AlarmManagerService的hal层分析
来源:互联网 发布:python兼职 编辑:程序博客网 时间:2024/05/16 16:14
之前我们分析过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机制。
- AlarmManagerService的hal层分析
- android关于GPS hal层的分析
- android关于GPS hal层的分析
- android关于GPS hal层的分析
- android关于GPS hal层的分析
- android关于GPS hal层的分析
- HAL向上层提供接口的分析
- Android HAL层分析
- 电子罗盘HAL层分析
- 电子罗盘HAL层分析
- Android Hal层简要分析
- Android Hal层简要分析
- Android 传感器hal层分析
- Android Hal层简要分析
- Android Hal层简要分析
- Android HAL层简要分析
- Android Hal层简要分析
- Android Hal层简要分析
- 多线程-GCD
- 如何判断对象已死
- Linux 下 Qt Creator 的安装使用
- centos 内核升级(2.6.32->3.19.0)
- 前端的一些学习资源
- AlarmManagerService的hal层分析
- loadrunner进阶——学习三、开发测试脚本
- RGB 色度空间转换
- 喝汽水问题
- Android图片旋转到固定方向方法
- python中通信模块
- Android中ListView嵌套导致高度错误
- UVa 133 The Dole Queue
- loadrunner进阶——学习四、集合点策略