android alarm driver &framework 关键流程
来源:互联网 发布:在线课堂软件 编辑:程序博客网 时间:2024/05/28 04:54
android alarm driver如下:
alarm-dev.c@\kernel\drivers\staging\android
static int __init alarm_dev_init(void){ int err; int i; err = misc_register(&alarm_device); if (err) return err; alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm, ALARM_REALTIME, devalarm_alarmhandler); hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS); alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm, ALARM_BOOTTIME, devalarm_alarmhandler); hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt, CLOCK_BOOTTIME, HRTIMER_MODE_ABS); hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { alarms[i].type = i; if (!is_wakeup(i)) alarms[i].u.hrt.function = devalarm_hrthandler; } wakeup_source_init(&alarm_wake_lock, "alarm"); return 0;}
driver init主要做了三件事,
1. 注册android alarm 设备:alarm_device。
2. 向linux alarm子系统注册alarm处理函数devalarm_alarmhandler,如果是允许唤醒系统的alarm,还会注册devalarm_hrthandler。当系统linux alarm到期时, 会回调这两个handler处理。
3. 初始化alarm 的wakeup source。
再细看handler里的处理:
static void devalarm_triggered(struct devalarm *alarm){ unsigned long flags; uint32_t alarm_type_mask = 1U << alarm->type; alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type); spin_lock_irqsave(&alarm_slock, flags); if (alarm_enabled & alarm_type_mask) { __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */ alarm_enabled &= ~alarm_type_mask; alarm_pending |= alarm_type_mask; wake_up(&alarm_wait_queue); } spin_unlock_irqrestore(&alarm_slock, flags);}
主要做了一个动作是唤醒alarm的等待队列alarm_wait_queue, 后面分析再看如何与这里对接 。
先看上层AlarmManagerService初始化的函数,
主要有两步, 一是call native init, 二是启动thread一直等alarm消息:
public AlarmManagerService(Context context) { mContext = context; mDescriptor = init();.... if (mDescriptor != -1) { mWaitThread.start(); } else { Slog.w(TAG, "Failed to open alarm driver. Falling back to a handler."); } }
其中AlarmManagerService是由System_server init时new出来:
initAndLoop()@SystemServer.java
Slog.i(TAG, "Alarm Manager"); alarm = new AlarmManagerService(context); ServiceManager.addService(Context.ALARM_SERVICE, alarm);
init对应初始化,完成alarm设备打开:
com_android_server_AlarmManagerService.cpp@ \frameworks\base\services\jni
static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj){ return open("/dev/alarm", O_RDWR);}
mwaitThread start后,一直循环block等待alarm driver消息, :
public void run() { ArrayList<Alarm> triggerList = new ArrayList<Alarm>(); while (true) { int result = waitForAlarm(mDescriptor);
native实现 :
static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd){ int result = 0; do { result = ioctl(fd, ANDROID_ALARM_WAIT); } while (result < 0 && errno == EINTR); if (result < 0) { ALOGE("Unable to wait on alarm: %s\n", strerror(errno)); return 0; } return result;}
ioctl对应driver逻辑:
static long alarm_do_ioctl(struct file *file, unsigned int cmd, struct timespec *ts){... case ANDROID_ALARM_WAIT: rv = alarm_wait(); break;
alarm_wait实现 如下, 此处会一直wait等待wake up alarm_wait_queue状态 , 就接上了最开始提到的向linux alarm子系统注册的alarm handler来wakeup的地方. 从而完成了具体alarm到期事件 向framework的通知 。
static int alarm_wait(void){ unsigned long flags; int rv = 0; spin_lock_irqsave(&alarm_slock, flags); alarm_dbg(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { __pm_relax(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) return rv; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); return rv;}
- android alarm driver &framework 关键流程
- Android学习之Alarm driver
- why Android add an alarm driver?
- android framework 启动流程
- android framework编译流程
- android framework 启动流程
- Android FrameWork 启动流程
- Android FrameWork 启动流程
- Android Framework 编译流程
- Android Framework--启动流程
- Android Framework层重启流程
- android alarm
- Android Alarm
- Android Video Playback----from Framework to Driver
- Android-Framework:Binder(3)-Binder Driver
- android framework关键知识提炼目录
- Alarm设置流程
- Android Framework启动流程分析
- C#反射 获取程序集信息和通过类名创建类实例
- Ajax SpringMvc 实现登录请求
- 介绍 Spring IoC 容器和 bean
- Activity管理 退出登录 或退出程序
- 如何安装MATLAB工具包
- android alarm driver &framework 关键流程
- jquery实现滚动条随着页面高度增加向下滚动
- 图片流,bitmap保存
- Android自定义ListView实现侧滑子菜单
- 设计模式C++实现(7)——外观模式、组合模式
- 邓白氏回访要填的信息
- AndroidStudio和Eclipse中app签名问题(SH1和MD5)
- Java基本数据类型
- python元组或运算 python-oracle接口问题 2016.06.30回顾