Android从上层到底层完整流程17页word资料Word文档下载推荐.docx
- 文档编号:8536034
- 上传时间:2023-05-11
- 格式:DOCX
- 页数:7
- 大小:18.92KB
Android从上层到底层完整流程17页word资料Word文档下载推荐.docx
《Android从上层到底层完整流程17页word资料Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Android从上层到底层完整流程17页word资料Word文档下载推荐.docx(7页珍藏版)》请在冰点文库上搜索。
if(!
enableSnoozeAlert(context)){
Alarmalarm=calculateNextAlert(context);
//new一个新的alarm
if(alarm!
=null){
enableAlert(context,alarm,alarm.time);
}else{
disableAlert(context);
}
然后继续调用到
privatestaticvoidenableAlert(Contextcontext,finalAlarmalarm,finallongatTimeInMillis){
.......
am.set(AlarmManager.RTC_WAKEUP,atTimeInMillis,sender);
//这里是RTC_WAKEUP,这就保证了即使系统睡眠了,都能唤醒,闹钟工作(android平台关机闹钟好像不行)
.....
然后就调用到了AlarmManager.java里面方法
publicvoidset(inttype,longtriggerAtTime,PendingIntentoperation){
try{
mService.set(type,triggerAtTime,operation);
}catch(RemoteExceptionex){
然后就调用到了AlarmManagerService.java
里面方法
publicvoidset(inttype,longtriggerAtTime,PendingIntentoperation){
setRepeating(type,triggerAtTime,0,operation);
然后继续调用
publicvoidsetRepeating(inttype,longtriggerAtTime,longinterval,
PendingIntentoperation)
{
synchronized(mLock){
Alarmalarm=newAlarm();
alarm.type=type;
alarm.when=triggerAtTime;
alarm.repeatInterval=interval;
alarm.operation=operation;
//Removethisalarmifalreadyscheduled.
removeLocked(operation);
if(localLOGV)Slog.v(TAG,"
set:
"
+alarm);
intindex=addAlarmLocked(alarm);
if(index==0)
setLocked(alarm);
然后就调用到
privatevoidsetLocked(Alarmalarm)
......//mDescriptor这里的文件是/dev/alarm
set(mDescriptor,alarm.type,alarmSeconds,alarmNanoseconds);
这里就调用到jni了
privatenativevoidset(intfd,inttype,longseconds,longnanoseconds);
这就调用到了com_android_server_AlarmManagerService.cpp里面
staticJNINativeMethodsMethods[]={
/*name,signature,funcPtr*/
{"
init"
"
()I"
(void*)android_server_AlarmManagerService_init},
close"
(I)V"
(void*)android_server_AlarmManagerService_close},
set"
(IIJJ)V"
(void*)android_server_AlarmManagerService_set},
{"
waitForAlarm"
(I)I"
(void*)android_server_AlarmManagerService_waitForAlarm},
setKernelTimezone"
(II)I"
(void*)android_server_AlarmManagerService_setKernelTimezone},
};
set对应的是android_server_AlarmManagerService_set,具体是
staticvoidandroid_server_AlarmManagerService_set(JNIEnv*env,jobjectobj,jintfd,jinttype,jlongseconds,jlongnanoseconds)
#ifHAVE_ANDROID_OS
structtimespects;
ts_sec=seconds;
ts_nsec=nanoseconds;
intresult=ioctl(fd,ANDROID_ALARM_SET(type),&
ts);
if(result<
0)
LOGE("
Unabletosetalarmto%lld.%09lld:
%s\n"
seconds,nanoseconds,strerror(errno));
#endif
然后ioctl就调用到了alarm-dev.c
staticlongalarm_ioctl(structfile*file,unsignedintcmd,unsignedlongarg)
caseANDROID_ALARM_SET(0):
if(copy_from_user(&
new_alarm_time,(void__user*)arg,sizeof(new_alarm_time))){
rv=-EFAULT;
gotoerr1;
from_old_alarm_set:
spin_lock_irqsave(&
alarm_slock,flags);
pr_alarm(IO,"
alarm%dset%ld.%09ld\n"
alarm_type,
new_alarm_time_sec,new_alarm_time_nsec);
alarm_enabled|=alarm_type_mask;
alarm_start_range(&
alarms[alarm_type],
timespec_to_ktime(new_alarm_time),
timespec_to_ktime(new_alarm_time));
spin_unlock_irqrestore(&
if(ANDROID_ALARM_BASE_CMD(cmd)!
=ANDROID_ALARM_SET_AND_WAIT(0)&
&
cmd!
=ANDROID_ALARM_SET_AND_WAIT_OLD)
break;
/*fallthough*/
caseANDROID_ALARM_SET_RTC:
new_rtc_time,(void__user*)arg,
sizeof(new_rtc_time))){
rv=alarm_set_rtc(new_rtc_time);
spin_lock_irqsave(&
alarm_pending|=ANDROID_ALARM_TIME_CHANGE_MASK;
wake_up(&
alarm_wait_queue);
spin_unlock_irqrestore(&
if(rv<
然后这边就调用到了alarm_start_range设置闹钟,alarm_set_rtc设置RTC
这两个函数在android_alarm.h声明,在alarm.c里实现。
这是android_alarm.h里面的声明
voidalarm_start_range(structalarm*alarm,ktime_tstart,ktime_tend);
intalarm_try_to_cancel(structalarm*alarm);
intalarm_cancel(structalarm*alarm);
ktime_talarm_get_elapsed_realtime(void);
/*setrtcwhilepreservingelapsedrealtime*/
intalarm_set_rtc(conststructtimespects);
下面看alarm.c里面实现:
intalarm_set_rtc(structtimespecnew_time)
ret=rtc_set_time(alarm_rtc_dev,&
rtc_new_rtc_time);
alarm.c
里面实现了alarm_suspend
alarm_resume函数,就是如果系统没有suspend的时候,设置闹钟并不会往rtc芯片的寄存器上写数据,因为不需要唤醒系统,所以闹钟数据时间什么的就通过上层写到设备文件/dev/alarm,里面就可以了,AlarmThread会不停的去轮寻下一个时间有没有闹钟,直接从设备文件/dev/alarm里面读取。
第二种,系统要是进入susupend的话,alarm的alarm_suspend就会写到下层的rtc芯片的寄存器上去,然后即使系统suspend之后,闹钟通过rtc也能唤醒系统,这里就调用到了interface.c里面
//这里面intrtc_set_alarm(structrtc_device*rtc,structrtc_wkalrm*alarm)差不多也是跟下面一样
intrtc_set_time(structrtc_device*rtc,structrtc_time*tm)
err=rtc->
ops->
set_time(rtc->
dev.parent,tm);
然后set_time就看到具体的是那个RTC芯片,这边我们是rtc-pcf8563.c
staticconststructrtc_class_opspcf8563_rtc_ops={
.read_time
=pcf8563_rtc_read_time,
.set_time
=pcf8563_rtc_set_time,
.read_alarm
=pcf8563_rtc_read_alarm,
.set_alarm
=pcf8563_rtc_set_alarm,
然后就到了
staticintpcf8563_rtc_set_time(structdevice*dev,structrtc_time*tm)
unsignedcharbuf[TIME_NUM];
intret;
ret=data_calc(buf,tm,TIME_NUM);
if(ret<
gotoout;
ret=i2c_smbus_write_i2c_block_data(pcf8563_info->
client,PCF8563_RTC_SEC,TIME_NUM,buf);
//这边就调用i2c统一接口,往pcf8563rtc芯片寄存器里面写出数据
out:
returnret;
到此,闹钟时间就已经写到rtc芯片的寄存器里面,第二个参数就是寄存器的名字,后面的buf就是要写入的时间,rtc芯片是额外供电的,所以系统suspend之后,系统kernel都关了,但是rtc里面还有电,寄存器里面数据还是有的(掉电就会丢失数据),所以闹钟到了,通过硬件中断机制就可以唤醒系统。
上面那个rtc下面有几十个rtc芯片驱动代码,没有结构基本一样,都有基本操作函数,注册函数,都是对各自芯片上特有的寄存器操作,为什么调用的是pcf8563rtc呢?
这个要看你系统用的是那个芯片,这个可以通过./kernel/kernel/kernel/.config
查看,这边的pcf8563rtc是当前系统正在使用的芯片型号
#CONFIG_RTC_DRV_ISL1208isnotset
#CONFIG_RTC_DRV_X1205isnotset
CONFIG_RTC_DRV_PCF8563=y
#CONFIG_RTC_DRV_PCF8583isnotset
#CONFIG_RTC_DRV_M41T80isnotset
下面是系统唤醒之后,闹钟怎么工作的流程,简单阐述
系统没有suspend的话直接走下面流程,如果suspend的话会被RTC唤醒,然后还是走下面的流程
privateclassAlarmThreadextendsThread
{
publicAlarmThread()
super("
AlarmManager"
);
publicvoidrun()
{
while(true)
intresult=waitForAlarm(mDescriptor);
//这里调用jni调用staticjintandroid_server_AlarmManagerService_waitForAlarm,主要还是对/dev/alarm
操作
Alarmalarm=it.next();
sendingalarm"
alarm.operation.send(mContext,0,
mBackgroundIntent.putExtra(
Intent.EXTRA_ALARM_COUNT,alarm.count),
mResultReceiver,mHandler);
staticjintandroid_server_AlarmManagerService_waitForAlarm(JNIEnv*env,jobjectobj,jintfd)
intresult=0;
do
result=ioctl(fd,ANDROID_ALARM_WAIT);
}while(result<
0&
errno==EINTR);
Unabletowaitonalarm:
strerror(errno));
return0;
returnresult;
AlarmManagerService
里面有个AlarmThread会一直轮询/dev/alarm文件,如果打开失败就直接返回,成功就会做一些动作,比如查找时间最近的alarm,比如睡眠被闹钟唤醒的时候,这边就发一个intent出去,然后在AlarmReceiver.java里面弹出里面会收到就会调用下面的
context.startActivity(alarmAlert);
然后弹出alarm
这个界面
Classc=AlarmAlert.class;
其中publicclassAlarmAlertextendsAlarmAlertFullScreen
所以系统睡眠之后被alarm唤醒弹出的alarm就是这边start的
publicclassAlarmReceiverextendsBroadcastReceiver{
/**IfthealarmisolderthanSTALE_WINDOW,ignore.
It
isprobablytheresultofatimeortimezonechange*/
privatefinalstaticintSTALE_WINDOW=30*60*1000;
@Override
publicvoidonReceive(Contextcontext,Intentintent){
.........
IntentalarmAlert=newIntent(context,c);
alarmAlert.putExtra(Alarms.ALARM_INTENT_EXTRA,alarm);
alarmAlert.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|Intent.FLAG_ACTIVITY_NO_USER_ACTION);
context.startActivity(alarmAlert);
........
到这里alarm就显示出来了
我个人添加的log,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 上层 到底 完整 流程 17 word 资料