http://www.mamicode.com/info-detail-399016.html

android开机动画启动流程

时间: 2014-12-31 18:34:49

标签:


从android的Surface Flinger服务启动分析知道,开机动画是在SurfaceFlinger实例通过调用startBootAnim()启动的。

下面我们就一起学习BootAnim是如何启动和结束的,我精读代码前都喜欢先描出框架图,以此图为基础再去研读会达到事半功倍的效果。好吧,直接上图。





内核起来后会启动第一个进程,即init进程。

init进程会根据init.rc配置启动surfaceflinger进程。


[cpp] view plain copy
  1. servicesurfaceflinger/system/bin/surfaceflinger
  2. classmain
  3. usersystem
  4. groupgraphicsdrmrpc
  5. onrestartrestartzygote

surfaceflinger进程便启动了,跟着就会跑进程的main()函数。


frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

[cpp] view plain copy
  1. intmain(intargc,char**argv){
  2. ....
  3. //instantiatesurfaceflinger
  4. sp<SurfaceFlinger>flinger=newSurfaceFlinger();//创建surfaceflinger服务实例
  5. ....
  6. flinger->init();
  7. //publishsurfaceflinger
  8. sp<IServiceManager>sm(defaultServiceManager());
  9. sm->addService(String16(SurfaceFlinger::getServiceName()),flinger,false);//注册到servicemanager里
  10. //runinthisthread
  11. flinger->run();//开跑
  12. return0;
  13. }

首先new一个SurfaceFlinger实例,然后init,然后run


frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

[cpp] view plain copy
  1. voidSurfaceFlinger::init(){
  2. ALOGI("SurfaceFlinger'smainthreadreadytorun."
  3. "InitializinggraphicsH/W...");
  4. .....
  5. //startbootanimation
  6. startBootAnim();//开始播放动画
  7. }

初始化graphics之后,就调用startBootAnim()播放开机动画。


[cpp] view plain copy
  1. voidSurfaceFlinger::startBootAnim(){
  2. //startbootanimation
  3. mBootFinished=false;
  4. property_set("service.bootanim.exit","0");//这个会有bootanimation进程周期检测,=1退出动画
  5. property_set("ctl.start","bootanim");//通过ctl.start命令启动bootanim
  6. }

把service.bootanim.exit属性设为0,这个属性bootanimation进程里会周期检查,=1时就退出动画,这里=0表示要播放动画。

后面通过ctl.start的命令启动bootanim进程,动画就开始播放了。


下面来到bootanimation的实现


frameworks/base/cmds/bootanimation/bootanimation_main.cpp

[cpp] view plain copy
  1. intmain(intargc,char**argv)
  2. {
  3. sp<ProcessState>proc(ProcessState::self());
  4. ProcessState::self()->startThreadPool();
  5. //createthebootanimationobject
  6. sp<BootAnimation>boot=newBootAnimation();//创建BootAnimation实例
  7. IPCThreadState::self()->joinThreadPool();//binder线程池,与surfaceflinger通信用的。
  8. }
  9. return0;
  10. }

new一个BootAnimation实例,然后建个binder线程池,因为BootAnimation在显示动画时要与SurfaceFlinger服务进程通信,所以要启个binder线程池。


frameworks/base/cmds/bootanimation/BootAnimation.cpp

[cpp] view plain copy
  1. BootAnimation::BootAnimation():Thread(false)
  2. {
  3. mSession=newSurfaceComposerClient();//创建一个对象
  4. }

创建实例时,构造函数就会被调用,new一个SurfaceComposerClient实例,他是用来与surfaceflinger通信的


[cpp] view plain copy
  1. voidBootAnimation::onFirstRef(){
  2. status_terr=mSession->linkToComposerDeath(this);//注册surfaceflinger死亡消息的通知书
  3. ALOGE_IF(err,"linkToComposerDeathfailed(%s)",strerror(-err));
  4. if(err==NO_ERROR){
  5. run("BootAnimation",PRIORITY_DISPLAY);//开跑
  6. }
  7. }


linkTocomposerDeath的作用是当surfaceflinger死掉是,BootAnimation就会得到通知。


如下,收到通知后就退出动画了,因为surfaceflinger都挂掉了,播放不了了。

[cpp] view plain copy
  1. voidBootAnimation::binderDied(constwp<IBinder>&who)
  2. {
  3. //woah,surfaceflingerdied!
  4. ALOGD("SurfaceFlingerdied,exiting...");
  5. //callingrequestExit()isnotenoughherebecausetheSurfacecode
  6. //mightbeblockedonaconditionvariablethatwillneverbeupdated.
  7. kill(getpid(),SIGKILL);//收到surfaceflinger死亡的消息,好吧自己也跟着去了。
  8. requestExit();
  9. }

另一个函数run()在BootAnimation的父类Thead里,用来创建一个线程并跑起来。


父类

system/core/libutils/Threads.cpp

[cpp] view plain copy
  1. status_tThread::run(constchar*name,int32_tpriority,size_tstack)
  2. {
  3. ...
  4. if(mCanCallJava){
  5. res=createThreadEtc(_threadLoop,//创建线程
  6. this,name,priority,stack,&mThread);
  7. }else{
  8. res=androidCreateRawThreadEtc(_threadLoop,
  9. this,name,priority,stack,&mThread);
  10. }
  11. ....
  12. }

创建_threadLoop线程

[cpp] view plain copy
  1. intThread::_threadLoop(void*user)
  2. {
  3. ....
  4. do{
  5. boolresult;
  6. if(first){
  7. first=false;
  8. self->mStatus=self->readyToRun();//这个函数被bootanimation重写了
  9. result=(self->mStatus==NO_ERROR);
  10. if(result&&!self->exitPending()){
  11. ...
  12. result=self->threadLoop();//这个函数被bootanimation重写了
  13. }
  14. }else{
  15. result=self->threadLoop();
  16. }
  17. ...
  18. return0;
  19. }

readyToRun函数实现

[cpp] view plain copy
  1. status_tBootAnimation::readyToRun(){
  2. mAssets.addDefaultAssets();
  3. sp<IBinder>dtoken(SurfaceComposerClient::getBuiltInDisplay(
  4. ISurfaceComposer::eDisplayIdMain));
  5. DisplayInfodinfo;
  6. status_tstatus=SurfaceComposerClient::getDisplayInfo(dtoken,&dinfo);
  7. if(status)
  8. return-1;
  9. charvalue[PROPERTY_VALUE_MAX];
  10. property_get("persist.panel.orientation",value,"0");
  11. intorient=atoi(value)/90;
  12. if(orient==eOrientation90||orient==eOrientation270){
  13. inttemp=dinfo.h;
  14. dinfo.h=dinfo.w;
  15. dinfo.w=temp;
  16. }
  17. RectdestRect(dinfo.w,dinfo.h);
  18. mSession->setDisplayProjection(dtoken,orient,destRect,destRect);
  19. //createthenativesurface
  20. sp<SurfaceControl>control=session()->createSurface(String8("BootAnimation"),
  21. dinfo.w,dinfo.h,PIXEL_FORMAT_RGB_565);
  22. SurfaceComposerClient::openGlobalTransaction();
  23. control->setLayer(0x40000000);
  24. SurfaceComposerClient::closeGlobalTransaction();
  25. sp<Surface>s=control->getSurface();
  26. //initializeopenglandegl
  27. constEGLintattribs[]={
  28. EGL_RED_SIZE,8,
  29. EGL_GREEN_SIZE,8,
  30. EGL_BLUE_SIZE,8,
  31. EGL_DEPTH_SIZE,0,
  32. EGL_NONE
  33. };
  34. EGLintw,h,dummy;
  35. EGLintnumConfigs;
  36. EGLConfigconfig;
  37. EGLSurfacesurface;
  38. EGLContextcontext;
  39. EGLDisplaydisplay=eglGetDisplay(EGL_DEFAULT_DISPLAY);
  40. eglInitialize(display,0,0);
  41. eglChooseConfig(display,attribs,&config,1,&numConfigs);
  42. surface=eglCreateWindowSurface(display,config,s.get(),NULL);
  43. context=eglCreateContext(display,config,NULL,NULL);
  44. eglQuerySurface(display,surface,EGL_WIDTH,&w);
  45. eglQuerySurface(display,surface,EGL_HEIGHT,&h);
  46. if(eglMakeCurrent(display,surface,surface,context)==EGL_FALSE)
  47. returnNO_INIT;
  48. mDisplay=display;
  49. mContext=context;
  50. mSurface=surface;
  51. mWidth=w;
  52. mHeight=h;
  53. mFlingerSurfaceControl=control;
  54. mFlingerSurface=s;
  55. mAndroidAnimation=true;
  56. //Ifthedevicehasencryptionturnedonorisinprocess
  57. //ofbeingencryptedweshowtheencryptedbootanimation.
  58. chardecrypt[PROPERTY_VALUE_MAX];
  59. property_get("vold.decrypt",decrypt,"");
  60. boolencryptedAnimation=atoi(decrypt)!=0||!strcmp("trigger_restart_min_framework",decrypt);
  61. if((encryptedAnimation&&
  62. (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE,R_OK)==0)&&
  63. (mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)==NO_ERROR))||
  64. ((access(USER_BOOTANIMATION_FILE,R_OK)==0)&&
  65. (mZip.open(USER_BOOTANIMATION_FILE)==NO_ERROR))||
  66. ((access(SYSTEM_BOOTANIMATION_FILE,R_OK)==0)&&
  67. (mZip.open(SYSTEM_BOOTANIMATION_FILE)==NO_ERROR))){
  68. mAndroidAnimation=false;
  69. }
  70. returnNO_ERROR;
  71. }

threadloop实现 [cpp] view plain copy
  1. boolBootAnimation::threadLoop()
  2. {
  3. boolr;
  4. if(mAndroidAnimation){
  5. r=android();//显示android默认动画
  6. }else{
  7. r=movie();//显示自定义的动画
  8. }
  9. //Noneedtoforceexitanymore
  10. property_set(EXIT_PROP_NAME,"0");
  11. eglMakeCurrent(mDisplay,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
  12. eglDestroyContext(mDisplay,mContext);
  13. eglDestroySurface(mDisplay,mSurface);
  14. mFlingerSurface.clear();
  15. mFlingerSurfaceControl.clear();
  16. eglTerminate(mDisplay);
  17. IPCThreadState::self()->stopProcess();
  18. returnr;
  19. }

movie()的实现 [cpp] view plain copy
  1. boolBootAnimation::movie()
  2. {
  3. //读取bootanimation.zip文件并解释
  4. //clearscreen
  5. //下面是循环显示
  6. for(inti=0;i<pcount;i++){
  7. constAnimation::Part&part(animation.parts[i]);
  8. constsize_tfcount=part.frames.size();
  9. glBindTexture(GL_TEXTURE_2D,0);
  10. for(intr=0;!part.count||r<part.count;r++){
  11. //Exitanynonplayuntilcompletepartsimmediately
  12. if(exitPending()&&!part.playUntilComplete)
  13. break;
  14. for(intj=0;j<fcount&&(!exitPending()||part.playUntilComplete);j++){
  15. constAnimation::Frame&frame(part.frames[j]);
  16. nsecs_tlastFrame=systemTime();
  17. if(r>0){
  18. glBindTexture(GL_TEXTURE_2D,frame.tid);
  19. }else{
  20. if(part.count!=1){
  21. glGenTextures(1,&frame.tid);
  22. glBindTexture(GL_TEXTURE_2D,frame.tid);
  23. glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  24. glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  25. }
  26. initTexture(
  27. frame.map->getDataPtr(),
  28. frame.map->getDataLength());
  29. }
  30. if(!clearReg.isEmpty()){
  31. Region::const_iteratorhead(clearReg.begin());
  32. Region::const_iteratortail(clearReg.end());
  33. glEnable(GL_SCISSOR_TEST);
  34. while(head!=tail){
  35. constRect&r(*head++);
  36. glScissor(r.left,mHeight-r.bottom,
  37. r.width(),r.height());
  38. glClear(GL_COLOR_BUFFER_BIT);
  39. }
  40. glDisable(GL_SCISSOR_TEST);
  41. }
  42. glDrawTexiOES(xc,yc,0,animation.width,animation.height);
  43. eglSwapBuffers(mDisplay,mSurface);
  44. nsecs_tnow=systemTime();
  45. nsecs_tdelay=frameDuration-(now-lastFrame);
  46. //ALOGD("%lld,%lld",ns2ms(now-lastFrame),ns2ms(delay));
  47. lastFrame=now;
  48. if(delay>0){
  49. structtimespecspec;
  50. spec.tv_sec=(now+delay)/1000000000;
  51. spec.tv_nsec=(now+delay)%1000000000;
  52. interr;
  53. do{
  54. err=clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&spec,NULL);
  55. }while(err<0&&errno==EINTR);
  56. }
  57. checkExit();//检测是否退出动画
  58. }
  59. usleep(part.pause*ns2us(frameDuration));
  60. //Forinfiniteparts,we'venowplayedthematleastonce,soperhapsexit
  61. if(exitPending()&&!part.count)
  62. break;
  63. }
  64. //freethetexturesforthispart
  65. if(part.count!=1){
  66. for(intj=0;j<fcount;j++){
  67. constAnimation::Frame&frame(part.frames[j]);
  68. glDeleteTextures(1,&frame.tid);
  69. }
  70. }
  71. }
  72. returnfalse;
  73. }

那么到movie为止,动画是在播放了,而且还在循环检测是否退出,即checkExit()


checkExit()的实现

[cpp] view plain copy
  1. voidBootAnimation::checkExit(){
  2. //Allowsurfaceflingertogracefullyrequestshutdown
  3. charvalue[PROPERTY_VALUE_MAX];
  4. property_get(EXIT_PROP_NAME,value,"0");//属性为1,说明要退出了
  5. intexitnow=atoi(value);
  6. if(exitnow){
  7. requestExit();
  8. }
  9. }

[cpp] view plain copy
  1. property_get(EXIT_PROP_NAME,value,"0");检测这个属性,=1就退出动画
[cpp] view plain copy
  1. #defineEXIT_PROP_NAME"service.bootanim.exit"
这个属性就是上面讲到的,等到launcher跑起来后就会置1

那动画是什么时候退出的?

当launcher应用程序主线程跑起来后,如果主线程处于空闲,就会向ActivityManagerService发送一个activityIdle的消息。

应用程序主线程是ActivityThread.java来描述的,activityIdle是这个类来实现的

[cpp] view plain copy
  1. privateclassIdlerimplementsMessageQueue.IdleHandler{
  2. ...
  3. IActivityManageram=ActivityManagerNative.getDefault();
  4. ...
  5. try{
  6. am.activityIdle(a.token,a.createdConfig,stopProfiling);
  7. a.createdConfig=null;
  8. }catch(RemoteExceptionex){
  9. //Ignore
  10. }
  11. ....
  12. }

上面的ActivityManagerNavtive.getDefault()得到am

来到frameworks/base/core/java/android/app/ActivityManagerNative.java

[cpp] view plain copy
  1. staticpublicIActivityManagergetDefault(){
  2. returngDefault.get();//getDefault的实现
  3. }

[cpp] view plain copy
  1. privatestaticfinalSingleton<IActivityManager>gDefault=newSingleton<IActivityManager>(){
  2. protectedIActivityManagercreate(){
  3. IBinderb=ServiceManager.getService("activity");
  4. if(false){
  5. Log.v("ActivityManager","defaultservicebinder="+b);
  6. }
  7. IActivityManageram=asInterface(b);
  8. if(false){
  9. Log.v("ActivityManager","defaultservice="+am);
  10. }
  11. returnam;
  12. }
  13. };

gDefault实际上是IActivityManager,往下看

[cpp] view plain copy
  1. classActivityManagerProxyimplementsIActivityManager
  2. {


ActivityManagerProxy实现了IActivityManager

那么am.activityIdle()就是ActivityManagerProxy里的函数,如下

[cpp] view plain copy
  1. publicvoidactivityIdle(IBindertoken,Configurationconfig,booleanstopProfiling)
  2. throwsRemoteException
  3. {
  4. ...
  5. mRemote.transact(ACTIVITY_IDLE_TRANSACTION,data,reply,IBinder.FLAG_ONEWAY);//发送ACTIVITY_IDLE_TRANSACTION
  6. ....
  7. }

发送了ACTIVITY_IDLE_TRANSACTION的进程间通信,这个消息被 ActivityManagerNative接收处理了。

[cpp] view plain copy
  1. caseACTIVITY_IDLE_TRANSACTION:{//收到消息
  2. data.enforceInterface(IActivityManager.descriptor);
  3. IBindertoken=data.readStrongBinder();
  4. Configurationconfig=null;
  5. if(data.readInt()!=0){
  6. config=Configuration.CREATOR.createFromParcel(data);
  7. }
  8. booleanstopProfiling=data.readInt()!=0;
  9. if(token!=null){
  10. activityIdle(token,config,stopProfiling);//这个函数在ActivityManagerService被重写
  11. }
  12. reply.writeNoException();
  13. returntrue;
  14. }

收到消息后就调用了activityIdle函数,这个函数被ActivityManagerService重写了,如下

frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

[cpp] view plain copy
  1. @Override
  2. publicfinalvoidactivityIdle(IBindertoken,Configurationconfig,booleanstopProfiling){
  3. finallongorigId=Binder.clearCallingIdentity();
  4. synchronized(this){
  5. ActivityStackstack=ActivityRecord.getStackLocked(token);
  6. if(stack!=null){
  7. ActivityRecordr=
  8. mStackSupervisor.activityIdleInternalLocked(token,false,config);
  9. if(stopProfiling){
  10. if((mProfileProc==r.app)&&(mProfileFd!=null)){
  11. try{
  12. mProfileFd.close();
  13. }catch(IOExceptione){
  14. }
  15. clearProfilerLocked();
  16. }
  17. }
  18. }
  19. }
  20. Binder.restoreCallingIdentity(origId);
  21. }

调用activityIdleInternalLocked函数,在下面实现

frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

[cpp] view plain copy
  1. finalActivityRecordactivityIdleInternalLocked(finalIBindertoken,booleanfromTimeout,
  2. Configurationconfig){
  3. ....
  4. if(enableScreen){
  5. mService.enableScreenAfterBoot();//调ActivityManagerService类的enableScreenAfterBoot()函数
  6. }
  7. ....
  8. if(activityRemoved){
  9. resumeTopActivitiesLocked();
  10. }
  11. returnr;
  12. }


来到frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

[cpp] view plain copy
  1. voidenableScreenAfterBoot(){
  2. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
  3. SystemClock.uptimeMillis());
  4. mWindowManager.enableScreenAfterBoot();//调WindowManagerService类里的enableScreenAfterBoot()函数
  5. synchronized(this){
  6. updateEventDispatchingLocked();
  7. }
  8. }

来到frameworks/base/services/java/com/android/server/wm/WindowManagerService.java


[cpp] view plain copy
  1. publicvoidenableScreenAfterBoot(){
  2. ....
  3. performEnableScreen();
  4. }

performEnableScreen()实现


[cpp] view plain copy
  1. publicvoidperformEnableScreen(){
  2. ..
  3. surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,//BOOT_FINISHED
  4. data,null,0);
  5. ....
  6. }

发送了FIRST_CALL_TRANSACTION的请求



因为从下面知道FIRST_CALL_TRANSACTION = BOOT_FINISHED

所以BnSurfaceComposer收到消息

frameworks/native/include/gui/ISurfaceComposer.h

[cpp] view plain copy
  1. classBnSurfaceComposer:publicBnInterface<ISurfaceComposer>{
  2. public:
  3. enum{
  4. //Note:BOOT_FINISHEDmustremainthisvalue,itiscalledfrom
  5. //JavabyActivityManagerService.
  6. BOOT_FINISHED=IBinder::FIRST_CALL_TRANSACTION,
  7. ...
  8. };
  9. virtualstatus_tonTransact(uint32_tcode,constParcel&data,
  10. Parcel*reply,uint32_tflags=0);
  11. };


[cpp] view plain copy
  1. </pre></p><p><spanstyle="color:#333333;">frameworks/native/libs/gui/ISurfaceComposer.cpp</span></p><p><spanstyle="color:#333333;"></span><prename="code"class="cpp">status_tBnSurfaceComposer::onTransact(
  2. uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
  3. {
  4. switch(code){
  5. ....
  6. caseBOOT_FINISHED:{
  7. CHECK_INTERFACE(ISurfaceComposer,data,reply);
  8. bootFinished();//调用bootFinished()
  9. returnNO_ERROR;
  10. }
  11. ....
  12. }
  13. //shouldbeunreachable
  14. returnNO_ERROR;
  15. }

bootFinished()函数BpSurfaceComposer里实现,但发现没有,他又发了一个BOOT_FINISHED,死循环了,其实没有。bootFinished()被 SurfaceFlinger类重写了

[cpp] view plain copy
  1. classBpSurfaceComposer:publicBpInterface<ISurfaceComposer>
  2. {
  3. virtualvoidbootFinished()
  4. {
  5. Parceldata,reply;
  6. data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
  7. remote()->transact(BnSurfaceComposer::BOOT_FINISHED,data,&reply);
  8. }

重写

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

[cpp] view plain copy
  1. voidSurfaceFlinger::bootFinished()
  2. {
  3. ...
  4. property_set("service.bootanim.exit","1");
  5. }

把service.bootanim.exit写成1,然后bootanimation进程的checkExit()检测到就退出进程,停止播放。

更多相关文章

  1. android 零散笔记不定期更新 v16
  2. Android动画之ViewAnimation和DrawableAnimation
  3. Android里解析AndroidManifest.xml的java文件
  4. android Animator详解
  5. Android(安卓)IPC 通讯机制源码分析
  6. activity属性设置大全
  7. android中的逐帧动画
  8. android animation中的参数interpolator详解
  9. 箭头函数的基础使用

随机推荐

  1. Android提权原理
  2. Android(安卓)SDK中tools详解
  3. RenderScript 让你的Android计算速度快的
  4. Android(安卓)Junit使用
  5. Android(安卓)控件布局常用属性
  6. 独家教程:用PHP编写Android应用程序
  7. Android(安卓)核心分析(13) -----Android
  8. Android实现书籍翻页效果--扩展版
  9. android环境搭建步骤
  10. android按键焦点事件分析(应用开发篇)