AMS启动Home(启动Launcher)

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic void systemReady(final Runnable goingCallback) {    ... ...    Slog.i(TAG, "System now ready");    ... ...    startHomeActivityLocked(mCurrentUserId, "systemReady"); //启动 Home}boolean startHomeActivityLocked(int userId, String reason) {    if (mStartHomeSetDefaultLauncherCount > 0) {            mStartHomeSetDefaultLauncherCount--;            boolean firstLaunch =             SystemProperties.getBoolean("persist.sys.sw.firstLaunch", true);            if(firstLaunch){                setDefaultLauncher(); //设置默认launcher                if (mStartHomeSetDefaultLauncherCount == 0) {                    SystemProperties.set("persist.sys.sw.firstLaunch", "false");                }            }        }    ... ...    Intent intent = getHomeIntent(); //获取Home的Intent    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);     //如果系统没有任何Home应用,aInfo == null,不会启动Home    //但是,如果系统是第一次启动或恢复出厂设置,会首先启动开机向导,此时aInfo != null    if (aInfo != null) {            intent.setComponent(new ComponentName( aInfo.applicationInfo.packageName, aInfo.name));            // Don't do this if the home app is currently being            // instrumented.            aInfo = new ActivityInfo(aInfo);            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);            ProcessRecord app = getProcessRecordLocked(aInfo.processName,                    aInfo.applicationInfo.uid, true);            if (app == null || app.instrumentationClass == null) {                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);                Slog.w("zhangc","startHomeActivity intent "+intent+"; aInfo "+aInfo+"; reason "+reason);                mStackSupervisor.startHomeActivity(intent, aInfo, reason); //此处启动Home应用            }    }}

Home应用启动后,回调AMS的activityIdle方法

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javapublic final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {    ... ...    ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token, false, config);}
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.javafinal ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, Configuration config) {    ... ...    if (isFrontStack(r.task.stack) || fromTimeout) {        booting = checkFinishBootingLocked();    }}

checkFinishBootingLocked会报告启动时间结束,以及检查是否是还在开机阶段,结束开机流程。当桌面已经拿到焦点显示好了,开机动画可以退出。在这里会修改AMS的mBooting全局变量为true,enableScreen也是true,发送Message给AMS进行处理。代码片段如下:

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.javaprivate boolean checkFinishBootingLocked() {        final boolean booting = mService.mBooting;        boolean enableScreen = false;        mService.mBooting = false;        if (!mService.mBooted) {            mService.mBooted = true;            enableScreen = true;        }        if (booting || enableScreen) {            mService.postFinishBooting(booting, enableScreen);        }        return booting;    }

postFinishBooting函数发送FINISH_BOOTING_MSG消息:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javavoid postFinishBooting(boolean finishBooting, boolean enableScreen) {        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,                finishBooting? 1 : 0, enableScreen ? 1 : 0));}

处理FINISH_BOOTING_MSG消息:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javafinal class MainHandler extends Handler {        public MainHandler(Looper looper) {            super(looper, null, true);        }        @Override        public void handleMessage(Message msg) {            ... ...            case FINISH_BOOTING_MSG: {                if (msg.arg1 != 0) {                    finishBooting();                }                if (msg.arg2 != 0) {                    enableScreenAfterBoot();                }                break;            }        }}

下面分别分析finishBootingenableScreenAfterBoot

finishBooting里面先判断开机动画有没有结束,如果没有结束,直接返回。如果已经结束,则经过一些处理,最后发送开机广播BOOT_COMPLETED。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javafinal void finishBooting() {        synchronized (this) {            if (!mBootAnimationComplete) {    //如果开机动画没有退出,直接返回                mCallFinishBooting = true;                return;            }            mCallFinishBooting = false;        }    // Tell anyone interested that we are done booting!    SystemProperties.set("sys.boot_completed", "1");    //设置属性,表明开机完成    ... ...    Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);    intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);    broadcastIntentLocked... ...     //发送开机广播}

那么,开机动画什么时候退出呢?继续往下看。

等待WMS准备好,SystemProperties.set("service.bootanim.exit", "1");,然后bootanimation退出。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javavoid enableScreenAfterBoot() {        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,                SystemClock.uptimeMillis());        mWindowManager.enableScreenAfterBoot(); //退出bootanimation        synchronized (this) {            updateEventDispatchingLocked();        }}

经过一系列调用,最后设置service.bootanim.exit这个属性。

property_set("service.bootanim.exit", "1");

frameworks/ base/services/core/java/com/android/server/wm/WindowManagerService.javaenableScreenAfterBoot()  ->     performEnableScreen()  ->               surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,  data, null, 0); ->frameworks/native/ services/surfaceflinger/SurfaceFlinger.cppbootFinished() ->    property_set("service.bootanim.exit", "1");  //将该属性设为1,开机动画退出。

 

更多相关文章

  1. Android attrs文件(自定义)属性详解
  2. ProgressBar播放动画
  3. AndroidManifest文件中android属性
  4. android:exported 属性详解
  5. Android中RelativeLayout布局各个xml相对布局属性的介绍和使用
  6. [android]控件ImageView的常用属性
  7. 【Android】TextView常用属性
  8. View动画

随机推荐

  1. android 组件使用()
  2. Android(安卓)Studio 添加另一个页面(Acti
  3. ADB调试命令大全
  4. android lcm驱动解读及调试
  5. 由于react-native-device-info出现的andr
  6. 如何使用 Bundle 传递数据?
  7. android 基于基站,apn,gps,wifi,network
  8. Android(安卓)View框架总结(三)View工作原
  9. ------------------Android中对GridView,
  10. appium自动化测试总结(转载liangww)