android开机动画启动流程
http://www.mamicode.com/info-detail-399016.html
android开机动画启动流程
标签:
从android的Surface Flinger服务启动分析知道,开机动画是在SurfaceFlinger实例通过调用startBootAnim()启动的。
下面我们就一起学习BootAnim是如何启动和结束的,我精读代码前都喜欢先描出框架图,以此图为基础再去研读会达到事半功倍的效果。好吧,直接上图。
内核起来后会启动第一个进程,即init进程。
init进程会根据init.rc配置启动surfaceflinger进程。
- servicesurfaceflinger/system/bin/surfaceflinger
- classmain
- usersystem
- groupgraphicsdrmrpc
- onrestartrestartzygote
surfaceflinger进程便启动了,跟着就会跑进程的main()函数。
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
- intmain(intargc,char**argv){
- ....
- //instantiatesurfaceflinger
- sp<SurfaceFlinger>flinger=newSurfaceFlinger();//创建surfaceflinger服务实例
- ....
- flinger->init();
- //publishsurfaceflinger
- sp<IServiceManager>sm(defaultServiceManager());
- sm->addService(String16(SurfaceFlinger::getServiceName()),flinger,false);//注册到servicemanager里
- //runinthisthread
- flinger->run();//开跑
- return0;
- }
首先new一个SurfaceFlinger实例,然后init,然后run
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
- voidSurfaceFlinger::init(){
- ALOGI("SurfaceFlinger'smainthreadreadytorun."
- "InitializinggraphicsH/W...");
- .....
- //startbootanimation
- startBootAnim();//开始播放动画
- }
初始化graphics之后,就调用startBootAnim()播放开机动画。
- voidSurfaceFlinger::startBootAnim(){
- //startbootanimation
- mBootFinished=false;
- property_set("service.bootanim.exit","0");//这个会有bootanimation进程周期检测,=1退出动画
- property_set("ctl.start","bootanim");//通过ctl.start命令启动bootanim
- }
把service.bootanim.exit属性设为0,这个属性bootanimation进程里会周期检查,=1时就退出动画,这里=0表示要播放动画。
后面通过ctl.start的命令启动bootanim进程,动画就开始播放了。
下面来到bootanimation的实现
frameworks/base/cmds/bootanimation/bootanimation_main.cpp
- intmain(intargc,char**argv)
- {
- sp<ProcessState>proc(ProcessState::self());
- ProcessState::self()->startThreadPool();
- //createthebootanimationobject
- sp<BootAnimation>boot=newBootAnimation();//创建BootAnimation实例
- IPCThreadState::self()->joinThreadPool();//binder线程池,与surfaceflinger通信用的。
- }
- return0;
- }
new一个BootAnimation实例,然后建个binder线程池,因为BootAnimation在显示动画时要与SurfaceFlinger服务进程通信,所以要启个binder线程池。
frameworks/base/cmds/bootanimation/BootAnimation.cpp
- BootAnimation::BootAnimation():Thread(false)
- {
- mSession=newSurfaceComposerClient();//创建一个对象
- }
创建实例时,构造函数就会被调用,new一个SurfaceComposerClient实例,他是用来与surfaceflinger通信的
- voidBootAnimation::onFirstRef(){
- status_terr=mSession->linkToComposerDeath(this);//注册surfaceflinger死亡消息的通知书
- ALOGE_IF(err,"linkToComposerDeathfailed(%s)",strerror(-err));
- if(err==NO_ERROR){
- run("BootAnimation",PRIORITY_DISPLAY);//开跑
- }
- }
如下,收到通知后就退出动画了,因为surfaceflinger都挂掉了,播放不了了。
[cpp] view plain copy- voidBootAnimation::binderDied(constwp<IBinder>&who)
- {
- //woah,surfaceflingerdied!
- ALOGD("SurfaceFlingerdied,exiting...");
- //callingrequestExit()isnotenoughherebecausetheSurfacecode
- //mightbeblockedonaconditionvariablethatwillneverbeupdated.
- kill(getpid(),SIGKILL);//收到surfaceflinger死亡的消息,好吧自己也跟着去了。
- requestExit();
- }
另一个函数run()在BootAnimation的父类Thead里,用来创建一个线程并跑起来。
父类
system/core/libutils/Threads.cpp
[cpp] view plain copy
- status_tThread::run(constchar*name,int32_tpriority,size_tstack)
- {
- ...
- if(mCanCallJava){
- res=createThreadEtc(_threadLoop,//创建线程
- this,name,priority,stack,&mThread);
- }else{
- res=androidCreateRawThreadEtc(_threadLoop,
- this,name,priority,stack,&mThread);
- }
- ....
- }
创建_threadLoop线程
[cpp] view plain copy
- intThread::_threadLoop(void*user)
- {
- ....
- do{
- boolresult;
- if(first){
- first=false;
- self->mStatus=self->readyToRun();//这个函数被bootanimation重写了
- result=(self->mStatus==NO_ERROR);
- if(result&&!self->exitPending()){
- ...
- result=self->threadLoop();//这个函数被bootanimation重写了
- }
- }else{
- result=self->threadLoop();
- }
- ...
- return0;
- }
readyToRun函数实现
[cpp] view plain copy- status_tBootAnimation::readyToRun(){
- mAssets.addDefaultAssets();
- sp<IBinder>dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
- DisplayInfodinfo;
- status_tstatus=SurfaceComposerClient::getDisplayInfo(dtoken,&dinfo);
- if(status)
- return-1;
- charvalue[PROPERTY_VALUE_MAX];
- property_get("persist.panel.orientation",value,"0");
- intorient=atoi(value)/90;
- if(orient==eOrientation90||orient==eOrientation270){
- inttemp=dinfo.h;
- dinfo.h=dinfo.w;
- dinfo.w=temp;
- }
- RectdestRect(dinfo.w,dinfo.h);
- mSession->setDisplayProjection(dtoken,orient,destRect,destRect);
- //createthenativesurface
- sp<SurfaceControl>control=session()->createSurface(String8("BootAnimation"),
- dinfo.w,dinfo.h,PIXEL_FORMAT_RGB_565);
- SurfaceComposerClient::openGlobalTransaction();
- control->setLayer(0x40000000);
- SurfaceComposerClient::closeGlobalTransaction();
- sp<Surface>s=control->getSurface();
- //initializeopenglandegl
- constEGLintattribs[]={
- EGL_RED_SIZE,8,
- EGL_GREEN_SIZE,8,
- EGL_BLUE_SIZE,8,
- EGL_DEPTH_SIZE,0,
- EGL_NONE
- };
- EGLintw,h,dummy;
- EGLintnumConfigs;
- EGLConfigconfig;
- EGLSurfacesurface;
- EGLContextcontext;
- EGLDisplaydisplay=eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(display,0,0);
- eglChooseConfig(display,attribs,&config,1,&numConfigs);
- surface=eglCreateWindowSurface(display,config,s.get(),NULL);
- context=eglCreateContext(display,config,NULL,NULL);
- eglQuerySurface(display,surface,EGL_WIDTH,&w);
- eglQuerySurface(display,surface,EGL_HEIGHT,&h);
- if(eglMakeCurrent(display,surface,surface,context)==EGL_FALSE)
- returnNO_INIT;
- mDisplay=display;
- mContext=context;
- mSurface=surface;
- mWidth=w;
- mHeight=h;
- mFlingerSurfaceControl=control;
- mFlingerSurface=s;
- mAndroidAnimation=true;
- //Ifthedevicehasencryptionturnedonorisinprocess
- //ofbeingencryptedweshowtheencryptedbootanimation.
- chardecrypt[PROPERTY_VALUE_MAX];
- property_get("vold.decrypt",decrypt,"");
- boolencryptedAnimation=atoi(decrypt)!=0||!strcmp("trigger_restart_min_framework",decrypt);
- if((encryptedAnimation&&
- (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE,R_OK)==0)&&
- (mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)==NO_ERROR))||
- ((access(USER_BOOTANIMATION_FILE,R_OK)==0)&&
- (mZip.open(USER_BOOTANIMATION_FILE)==NO_ERROR))||
- ((access(SYSTEM_BOOTANIMATION_FILE,R_OK)==0)&&
- (mZip.open(SYSTEM_BOOTANIMATION_FILE)==NO_ERROR))){
- mAndroidAnimation=false;
- }
- returnNO_ERROR;
- }
threadloop实现 [cpp] view plain copy
- boolBootAnimation::threadLoop()
- {
- boolr;
- if(mAndroidAnimation){
- r=android();//显示android默认动画
- }else{
- r=movie();//显示自定义的动画
- }
- //Noneedtoforceexitanymore
- property_set(EXIT_PROP_NAME,"0");
- eglMakeCurrent(mDisplay,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
- eglDestroyContext(mDisplay,mContext);
- eglDestroySurface(mDisplay,mSurface);
- mFlingerSurface.clear();
- mFlingerSurfaceControl.clear();
- eglTerminate(mDisplay);
- IPCThreadState::self()->stopProcess();
- returnr;
- }
movie()的实现 [cpp] view plain copy
- boolBootAnimation::movie()
- {
- //读取bootanimation.zip文件并解释
- //clearscreen
- //下面是循环显示
- for(inti=0;i<pcount;i++){
- constAnimation::Part&part(animation.parts[i]);
- constsize_tfcount=part.frames.size();
- glBindTexture(GL_TEXTURE_2D,0);
- for(intr=0;!part.count||r<part.count;r++){
- //Exitanynonplayuntilcompletepartsimmediately
- if(exitPending()&&!part.playUntilComplete)
- break;
- for(intj=0;j<fcount&&(!exitPending()||part.playUntilComplete);j++){
- constAnimation::Frame&frame(part.frames[j]);
- nsecs_tlastFrame=systemTime();
- if(r>0){
- glBindTexture(GL_TEXTURE_2D,frame.tid);
- }else{
- if(part.count!=1){
- glGenTextures(1,&frame.tid);
- glBindTexture(GL_TEXTURE_2D,frame.tid);
- glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glTexParameterx(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- }
- initTexture(
- frame.map->getDataPtr(),
- frame.map->getDataLength());
- }
- if(!clearReg.isEmpty()){
- Region::const_iteratorhead(clearReg.begin());
- Region::const_iteratortail(clearReg.end());
- glEnable(GL_SCISSOR_TEST);
- while(head!=tail){
- constRect&r(*head++);
- glScissor(r.left,mHeight-r.bottom,
- r.width(),r.height());
- glClear(GL_COLOR_BUFFER_BIT);
- }
- glDisable(GL_SCISSOR_TEST);
- }
- glDrawTexiOES(xc,yc,0,animation.width,animation.height);
- eglSwapBuffers(mDisplay,mSurface);
- nsecs_tnow=systemTime();
- nsecs_tdelay=frameDuration-(now-lastFrame);
- //ALOGD("%lld,%lld",ns2ms(now-lastFrame),ns2ms(delay));
- lastFrame=now;
- if(delay>0){
- structtimespecspec;
- spec.tv_sec=(now+delay)/1000000000;
- spec.tv_nsec=(now+delay)%1000000000;
- interr;
- do{
- err=clock_nanosleep(CLOCK_MONOTONIC,TIMER_ABSTIME,&spec,NULL);
- }while(err<0&&errno==EINTR);
- }
- checkExit();//检测是否退出动画
- }
- usleep(part.pause*ns2us(frameDuration));
- //Forinfiniteparts,we'venowplayedthematleastonce,soperhapsexit
- if(exitPending()&&!part.count)
- break;
- }
- //freethetexturesforthispart
- if(part.count!=1){
- for(intj=0;j<fcount;j++){
- constAnimation::Frame&frame(part.frames[j]);
- glDeleteTextures(1,&frame.tid);
- }
- }
- }
- returnfalse;
- }
那么到movie为止,动画是在播放了,而且还在循环检测是否退出,即checkExit()
checkExit()的实现
[cpp] view plain copy- voidBootAnimation::checkExit(){
- //Allowsurfaceflingertogracefullyrequestshutdown
- charvalue[PROPERTY_VALUE_MAX];
- property_get(EXIT_PROP_NAME,value,"0");//属性为1,说明要退出了
- intexitnow=atoi(value);
- if(exitnow){
- requestExit();
- }
- }
[cpp] view plain copy
- property_get(EXIT_PROP_NAME,value,"0");检测这个属性,=1就退出动画
- #defineEXIT_PROP_NAME"service.bootanim.exit"
那动画是什么时候退出的?
当launcher应用程序主线程跑起来后,如果主线程处于空闲,就会向ActivityManagerService发送一个activityIdle的消息。
应用程序主线程是ActivityThread.java来描述的,activityIdle是这个类来实现的
[cpp] view plain copy
- privateclassIdlerimplementsMessageQueue.IdleHandler{
- ...
- IActivityManageram=ActivityManagerNative.getDefault();
- ...
- try{
- am.activityIdle(a.token,a.createdConfig,stopProfiling);
- a.createdConfig=null;
- }catch(RemoteExceptionex){
- //Ignore
- }
- ....
- }
上面的ActivityManagerNavtive.getDefault()得到am
来到frameworks/base/core/java/android/app/ActivityManagerNative.java
[cpp] view plain copy
- staticpublicIActivityManagergetDefault(){
- returngDefault.get();//getDefault的实现
- }
[cpp] view plain copy
- privatestaticfinalSingleton<IActivityManager>gDefault=newSingleton<IActivityManager>(){
- protectedIActivityManagercreate(){
- IBinderb=ServiceManager.getService("activity");
- if(false){
- Log.v("ActivityManager","defaultservicebinder="+b);
- }
- IActivityManageram=asInterface(b);
- if(false){
- Log.v("ActivityManager","defaultservice="+am);
- }
- returnam;
- }
- };
gDefault实际上是IActivityManager,往下看
[cpp] view plain copy
- classActivityManagerProxyimplementsIActivityManager
- {
那么am.activityIdle()就是ActivityManagerProxy里的函数,如下
[cpp] view plain copy
- publicvoidactivityIdle(IBindertoken,Configurationconfig,booleanstopProfiling)
- throwsRemoteException
- {
- ...
- mRemote.transact(ACTIVITY_IDLE_TRANSACTION,data,reply,IBinder.FLAG_ONEWAY);//发送ACTIVITY_IDLE_TRANSACTION
- ....
- }
发送了ACTIVITY_IDLE_TRANSACTION的进程间通信,这个消息被 ActivityManagerNative接收处理了。
[cpp] view plain copy
- caseACTIVITY_IDLE_TRANSACTION:{//收到消息
- data.enforceInterface(IActivityManager.descriptor);
- IBindertoken=data.readStrongBinder();
- Configurationconfig=null;
- if(data.readInt()!=0){
- config=Configuration.CREATOR.createFromParcel(data);
- }
- booleanstopProfiling=data.readInt()!=0;
- if(token!=null){
- activityIdle(token,config,stopProfiling);//这个函数在ActivityManagerService被重写
- }
- reply.writeNoException();
- returntrue;
- }
收到消息后就调用了activityIdle函数,这个函数被ActivityManagerService重写了,如下
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
[cpp] view plain copy
- @Override
- publicfinalvoidactivityIdle(IBindertoken,Configurationconfig,booleanstopProfiling){
- finallongorigId=Binder.clearCallingIdentity();
- synchronized(this){
- ActivityStackstack=ActivityRecord.getStackLocked(token);
- if(stack!=null){
- ActivityRecordr=
- mStackSupervisor.activityIdleInternalLocked(token,false,config);
- if(stopProfiling){
- if((mProfileProc==r.app)&&(mProfileFd!=null)){
- try{
- mProfileFd.close();
- }catch(IOExceptione){
- }
- clearProfilerLocked();
- }
- }
- }
- }
- Binder.restoreCallingIdentity(origId);
- }
调用activityIdleInternalLocked函数,在下面实现
frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
[cpp] view plain copy
- finalActivityRecordactivityIdleInternalLocked(finalIBindertoken,booleanfromTimeout,
- Configurationconfig){
- ....
- if(enableScreen){
- mService.enableScreenAfterBoot();//调ActivityManagerService类的enableScreenAfterBoot()函数
- }
- ....
- if(activityRemoved){
- resumeTopActivitiesLocked();
- }
- returnr;
- }
来到frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
[cpp] view plain copy
- voidenableScreenAfterBoot(){
- EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
- SystemClock.uptimeMillis());
- mWindowManager.enableScreenAfterBoot();//调WindowManagerService类里的enableScreenAfterBoot()函数
- synchronized(this){
- updateEventDispatchingLocked();
- }
- }
来到frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
[cpp] view plain copy
- publicvoidenableScreenAfterBoot(){
- ....
- performEnableScreen();
- }
performEnableScreen()实现
[cpp] view plain copy
- publicvoidperformEnableScreen(){
- ..
- surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,//BOOT_FINISHED
- data,null,0);
- ....
- }
发送了FIRST_CALL_TRANSACTION的请求
因为从下面知道FIRST_CALL_TRANSACTION = BOOT_FINISHED
所以BnSurfaceComposer收到消息
frameworks/native/include/gui/ISurfaceComposer.h
[cpp] view plain copy
- classBnSurfaceComposer:publicBnInterface<ISurfaceComposer>{
- public:
- enum{
- //Note:BOOT_FINISHEDmustremainthisvalue,itiscalledfrom
- //JavabyActivityManagerService.
- BOOT_FINISHED=IBinder::FIRST_CALL_TRANSACTION,
- ...
- };
- virtualstatus_tonTransact(uint32_tcode,constParcel&data,
- Parcel*reply,uint32_tflags=0);
- };
[cpp] view plain copy
- </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(
- uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
- {
- switch(code){
- ....
- caseBOOT_FINISHED:{
- CHECK_INTERFACE(ISurfaceComposer,data,reply);
- bootFinished();//调用bootFinished()
- returnNO_ERROR;
- }
- ....
- }
- //shouldbeunreachable
- returnNO_ERROR;
- }
bootFinished()函数BpSurfaceComposer里实现,但发现没有,他又发了一个BOOT_FINISHED,死循环了,其实没有。bootFinished()被 SurfaceFlinger类重写了
[cpp] view plain copy
- classBpSurfaceComposer:publicBpInterface<ISurfaceComposer>
- {
- virtualvoidbootFinished()
- {
- Parceldata,reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::BOOT_FINISHED,data,&reply);
- }
重写
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
[cpp] view plain copy
- voidSurfaceFlinger::bootFinished()
- {
- ...
- property_set("service.bootanim.exit","1");
- }
把service.bootanim.exit写成1,然后bootanimation进程的checkExit()检测到就退出进程,停止播放。
更多相关文章
- android中的逐帧动画
- Android通过共享用户ID来实现多Activity进程共享
- Android 中 动画效果实现
- Android 转场动画
- Android使用View类动画
- Android 自定义PopupWindow动画效果
- Android之进程查看,关闭(可操作所有进程)
- 个性进度条--------菊花加载----Android 播放动画