您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Android从上层到底层完整流程
Android上层界面到内核代码的完整的流程分析,以alarm为例子很久之前写的一个流程文档,从上层界面一直调用到内核的过程,最近同事跟我要,我看了下又在整理了下,纯属个人分析(不过都运行验证过),不对的请大牛指出。Alarm调用流程,alarm的流程实现了从上层应用一直到下面driver的调用流程,下面简单阐述:涉及代码;./packages/apps/DeskClock/src/com/android/deskclock/Alarms.java./frameworks/base/core/java/android/app/AlarmManager.java./frameworks/base/services/java/com/android/server/AlarmManagerService.java./frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp./kernel/kernel/drivers/rtc/alarm-dev.c./kernel/kernel/include/linux/android_alarm.h./kernel/kernel/drivers/rtc/alarm.c./kernel/kernel/drivers/rtc/interface.c./kernel/kernel/drivers/rtc/rtc-pcf8563.c/packages/apps/DeskClock/src/com/android/deskclock/AlarmReceiver.java./kernel/arch/arm/configs/mmp2_android_defconfig./kernel/kernel/kernel/.config点击Clock应用程序,然后设置新闹钟,会调到Alarms.java里面的publicstaticlongsetAlarm(Contextcontext,Alarmalarm){....setNextAlert(context);....}然后这里面也会调用到publicstaticvoidsetNextAlert(finalContextcontext){if(!enableSnoozeAlert(context)){Alarmalarm=calculateNextAlert(context);//new一个新的alarmif(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/alarmset(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_OSstructtimespects;ts.tv_sec=seconds;ts.tv_nsec=nanoseconds;intresult=ioctl(fd,ANDROID_ALARM_SET(type),&ts);if(result0){LOGE(Unabletosetalarmto%lld.%09lld:%s\n,seconds,nanoseconds,strerror(errno));}#endif}然后ioctl就调用到了alarm-dev.cstaticlongalarm_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.tv_sec,new_alarm_time.tv_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(&alarm_slock,flags);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:if(copy_from_user(&new_rtc_time,(void__user*)arg,sizeof(new_rtc_time))){rv=-EFAULT;gotoerr1;}rv=alarm_set_rtc(new_rtc_time);spin_lock_irqsave(&alarm_slock,flags);alarm_pending|=ANDROID_ALARM_TIME_CHANGE_MASK;wake_up(&alarm_wait_queue);spin_unlock_irqrestore(&alarm_slock,flags);if(rv0)gotoerr1;break;....}然后这边就调用到了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_suspendalarm_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,struct
本文标题:Android从上层到底层完整流程
链接地址:https://www.777doc.com/doc-634555 .html