Android11开机动画退出流程分析

在开机动画执行的循环里,都会调用checkExit来检查是否要退出开机动画

//frameworks\base\cmds\bootanimation
bool BootAnimation::android() {
   //......
    do {
        checkExit();
    } while (!exitPending());//调用requestExit之后,exitPending()返回true,退出循环
    //......

来看一下checkExit方法

//frameworks\base\cmds\bootanimation
void BootAnimation::checkExit() {
	char value[PROPERTY_VALUE_MAX];
    property_get(EXIT_PROP_NAME, value, "0");
    int exitnow = atoi(value);
    if (exitnow) {
		requestExit();
        mCallbacks->shutdown();
	}
}

其中 EXIT_PROP_NAME为 service.bootanim.exit,当检测到该属性的值不为0时,就调用 requestExit 退出动画。系统是在WindowManagerService中的performEnableScreen方法中,设置了该属性

private void performEnableScreen() {
        synchronized (mGlobalLock) {
			//......
			if (!mBootAnimationStopped) {
                Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
                // stop boot animation
                // formerly we would just kill the process, but we now ask it to exit so it
                // can choose where to stop the animation.
                SystemProperties.set("service.bootanim.exit", "1");
                mBootAnimationStopped = true;
            }
            //......
            try {
                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                if (surfaceFlinger != null) {
                    ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                    Parcel data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
                            data, null, 0); //这里最终调用到surfaceFlinger中,也会设置service.bootanim.exit这个值
                    data.recycle();
                }
            } catch (RemoteException ex) {
                ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");
            }
		}
		//......
}

来分析一下 performEnableScreen 的调用栈。在performEnableScreen 的三个地方,分别加了打印信息

1,3432行添加:
android.util.Log.d("test1","performEnableScreen1 mDisplayEnabled:"+mDisplayEnabled+",mForceDisplayEnabled:"											+mForceDisplayEnabled+",mShowingBootMessages:"+mShowingBootMessages+",mSystemBooted:"+mSystemBooted,new Exception());
2,3463行添加:
android.util.Log.d("test1","performEnableScreen2:",new Exception());
3,3477 行添加:
android.util.Log.d("test1","performEnableScreen3:",new Exception());

调用栈信息如下

03-11 16:49:15.662   445   479 D test1   : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.662   445   479 D test1   : java.lang.Exception
03-11 16:49:15.662   445   479 D test1   :      at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.662   445   479 D test1   :      at com.android.server.wm.WindowManagerService.enableScreenAfterBoot(WindowManagerService.java:3381)
03-11 16:49:15.662   445   479 D test1   :      at com.android.server.wm.ActivityTaskManagerService$LocalService.enableScreenAfterBoot(ActivityTaskManagerService.java:6468)
03-11 16:49:15.662   445   479 D test1   :      at com.android.server.wm.ActivityTaskManagerService.lambda$postFinishBooting$7$ActivityTaskManagerService(ActivityTaskManagerService.java:5658)
03-11 16:49:15.662   445   479 D test1   :      at com.android.server.wm.-$$Lambda$ActivityTaskManagerService$hgT7_BsCohDVg6qQfaw5Xpx0-yQ.run(Unknown Source:6)
03-11 16:49:15.662   445   479 D test1   :      at android.os.Handler.handleCallback(Handler.java:938)
03-11 16:49:15.662   445   479 D test1   :      at android.os.Handler.dispatchMessage(Handler.java:99)
03-11 16:49:15.662   445   479 D test1   :      at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.662   445   479 D test1   :      at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.662   445   479 D test1   :      at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.674   445   479 D test1   : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.674   445   479 D test1   : java.lang.Exception
03-11 16:49:15.674   445   479 D test1   :      at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.674   445   479 D test1   :      at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.674   445   479 D test1   :      at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4991)
03-11 16:49:15.674   445   479 D test1   :      at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.674   445   479 D test1   :      at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.674   445   479 D test1   :      at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.674   445   479 D test1   :      at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.684   445   479 D test1   : performEnableScreen2:
03-11 16:49:15.684   445   479 D test1   : java.lang.Exception
03-11 16:49:15.684   445   479 D test1   :      at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3463)
03-11 16:49:15.684   445   479 D test1   :      at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.684   445   479 D test1   :      at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4991)
03-11 16:49:15.684   445   479 D test1   :      at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.684   445   479 D test1   :      at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.684   445   479 D test1   :      at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.684   445   479 D test1   :      at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.690   445   479 D test1   : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.690   445   479 D test1   : java.lang.Exception
03-11 16:49:15.690   445   479 D test1   :      at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.690   445   479 D test1   :      at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.690   445   479 D test1   :      at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4991)
03-11 16:49:15.690   445   479 D test1   :      at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.690   445   479 D test1   :      at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.690   445   479 D test1   :      at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.690   445   479 D test1   :      at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.944   445   479 D test1   : performEnableScreen1 mDisplayEnabled:false,mForceDisplayEnabled:false,mShowingBootMessages:false,mSystemBooted:true
03-11 16:49:15.944   445   479 D test1   : java.lang.Exception
03-11 16:49:15.944   445   479 D test1   :      at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3432)
03-11 16:49:15.944   445   479 D test1   :      at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.944   445   479 D test1   :      at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:5114)
03-11 16:49:15.944   445   479 D test1   :      at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.944   445   479 D test1   :      at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.944   445   479 D test1   :      at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.944   445   479 D test1   :      at com.android.server.ServiceThread.run(ServiceThread.java:44)
03-11 16:49:15.947   445   479 D test1   : performEnableScreen3:
03-11 16:49:15.947   445   479 D test1   : java.lang.Exception
03-11 16:49:15.947   445   479 D test1   :      at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3477)
03-11 16:49:15.947   445   479 D test1   :      at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:317)
03-11 16:49:15.947   445   479 D test1   :      at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:5114)
03-11 16:49:15.947   445   479 D test1   :      at android.os.Handler.dispatchMessage(Handler.java:106)
03-11 16:49:15.947   445   479 D test1   :      at android.os.Looper.loop(Looper.java:223)
03-11 16:49:15.947   445   479 D test1   :      at android.os.HandlerThread.run(HandlerThread.java:67)
03-11 16:49:15.947   445   479 D test1   :      at com.android.server.ServiceThread.run(ServiceThread.java:44)

**可以看出:

  1. 首先通过调用ActivityTaskManagerService的 5658行(postFinishBooting方法)执行performEnableScreen方法
  2. 第一步调用没有执行到设置退出开机动画的属性,就直接返回了
  3. 通过调用WindowManagerService的 4991行,再次执行performEnableScreen方法,此时可以执行到设置退出开机动画属性的地方,开机动画退出
  4. 最后也会通过WindowManagerService的5114行,调用performEnableScreen**

分别来看一下这三个调用的地方

1,ActivityTaskManagerService的 5658行即postFinishBooting

在FallbackHome resume的时候,会添加一个 IdleHandler

@Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
	//......
	 Looper.myQueue().addIdleHandler(new Idler());
}

没有Message消息时,执行此IdleHandler

private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
           //......
           if (a != null) {
                mNewActivities = null;
                IActivityTaskManager am = ActivityTaskManager.getService();
                ActivityClientRecord prev;
                do {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null && a.activity.mFinished));
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();

			//......

进而调用到ActivityTaskManagerService的activityIdle函数中,调用栈如下

activityIdle Name:com.android.settings.FallbackHome
03-11 16:49:15.628   445  1059 D test1   : java.lang.Exception
03-11 16:49:15.628   445  1059 D test1   :      at com.android.server.wm.ActivityTaskManagerService.activityIdle(ActivityTaskManagerService.java:1807)
03-11 16:49:15.628   445  1059 D test1   :      at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1920)
03-11 16:49:15.628   445  1059 D test1   :      at android.os.Binder.execTransactInternal(Binder.java:1159)
03-11 16:49:15.628   445  1059 D test1   :      at android.os.Binder.execTransact(Binder.java:1123)

通过一步步的调用,最终调用到postFinishBooting,调用信息如下

activityIdle
	mStackSupervisor.activityIdleInternal(r, false /* fromTimeout */,false /* processPausingActivities */, config);
		checkFinishBootingLocked
			 mService.postFinishBooting(booting, enableScreen);
			 	mInternal.enableScreenAfterBoot(isBooted());
			 		mWindowManager.enableScreenAfterBoot();
			 			performEnableScreen();

2,WindowManagerService 的 4991行
在4991行是接收到ENABLE_SCREEN的消息,然后执行performEnableScreen

case ENABLE_SCREEN: {
	performEnableScreen();
	break;
 }

在enableScreenIfNeeded 方法中发送消息

@Override
    public void enableScreenIfNeeded() {
        synchronized (mGlobalLock) {
            enableScreenIfNeededLocked();
        }
    }
void enableScreenIfNeededLocked() {
       //......
        if (mDisplayEnabled) {
            return;
        }
        if (!mSystemBooted && !mShowingBootMessages) {
            return;
        }
        mH.sendEmptyMessage(H.ENABLE_SCREEN);
    }
    

enableScreenIfNeeded 在PhoneWindowManager中被调用

private void finishScreenTurningOn() {
	//......
	if (enableScreen) {
            try {
                mWindowManager.enableScreenIfNeeded();
            } catch (RemoteException unhandled) {
            }
        }

}

在所有的windows都绘制完成之后,发送MSG_WINDOW_MANAGER_DRAWN_COMPLETE消息,最终调用到finishScreenTurningOn

3,WindowManagerService的5114行
调用checkBootAnimationCompleteLocked ,如果开机完成则调用performEnableScreen

case CHECK_IF_BOOT_ANIMATION_FINISHED: {
                    final boolean bootAnimationComplete;
                    synchronized (mGlobalLock) {
                        ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
                        bootAnimationComplete = checkBootAnimationCompleteLocked();
                    }
                    if (bootAnimationComplete) {
                        performEnableScreen();
                    }
                    break;
                }

你可能感兴趣的:(Android,系统开机启动流程,android,java)