接上一篇文章:Android启动流程简析(二)

7. SystemServer启动介绍

SystemServer需要从Zygote fork SystemServer开始分析,主要是设置参数,然后调用Zygote的forkSystemServer方法,再判断是否有SecondaryZygote启动,有则等待其启动,无则返回

private static Runnable forkSystemServer(String abiList, String socketName,        ZygoteServer zygoteServer) {    long capabilities = posixCapabilitiesAsBits(        OsConstants.CAP_IPC_LOCK,        OsConstants.CAP_KILL,        OsConstants.CAP_NET_ADMIN,        OsConstants.CAP_NET_BIND_SERVICE,        OsConstants.CAP_NET_BROADCAST,        OsConstants.CAP_NET_RAW,        OsConstants.CAP_SYS_MODULE,        OsConstants.CAP_SYS_NICE,        OsConstants.CAP_SYS_PTRACE,        OsConstants.CAP_SYS_TIME,        OsConstants.CAP_SYS_TTY_CONFIG,        OsConstants.CAP_WAKE_ALARM    );    /* Containers run without this capability, so avoid setting it in that case */    if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {        capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);    }    /* Hardcoded command line to start the system server */    String args[] = {        "--setuid=1000",        "--setgid=1000",        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",        "--capabilities=" + capabilities + "," + capabilities,        "--nice-name=system_server",        "--runtime-args",        "com.android.server.SystemServer",    };    ZygoteConnection.Arguments parsedArgs = null;    int pid;    try {        parsedArgs = new ZygoteConnection.Arguments(args);        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);        /* Request to fork the system server process */        pid = Zygote.forkSystemServer(                parsedArgs.uid, parsedArgs.gid,                parsedArgs.gids,                parsedArgs.debugFlags,                null,                parsedArgs.permittedCapabilities,                parsedArgs.effectiveCapabilities);    } catch (IllegalArgumentException ex) {        throw new RuntimeException(ex);    }    /* For child process */    if (pid == 0) {        if (hasSecondZygote(abiList)) {            waitForSecondaryZygote(socketName);        }        zygoteServer.closeServerSocket();        return handleSystemServerProcess(parsedArgs);    }    return null;}

Zygote的forkSystemServer方法主要是调用了native方法nativeForkSystemServer,在native层进行fork动作,并设置pid、gid、selinux安全上下文等,最后启动com.android.server.SystemServer

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {    VM_HOOKS.preFork();    // Resets nice priority for zygote process.    resetNicePriority();    int pid = nativeForkSystemServer(            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);    // Enable tracing as soon as we enter the system_server.    if (pid == 0) {        Trace.setTracingEnabled(true, debugFlags);    }    VM_HOOKS.postForkCommon();    return pid;}
static const JNINativeMethod gMethods[] = {    { "nativeForkAndSpecialize",      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I",      (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },    { "nativeForkSystemServer", "(II[II[[IJJ)I",      (void *) com_android_internal_os_Zygote_nativeForkSystemServer },    { "nativeAllowFileAcrossFork", "(Ljava/lang/String;)V",      (void *) com_android_internal_os_Zygote_nativeAllowFileAcrossFork },    { "nativeUnmountStorageOnInit", "()V",      (void *) com_android_internal_os_Zygote_nativeUnmountStorageOnInit },    { "nativePreApplicationInit", "()V",      (void *) com_android_internal_os_Zygote_nativePreApplicationInit }};
static jint com_android_internal_os_Zygote_nativeForkSystemServer(        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,        jlong effectiveCapabilities) {  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,                                      debug_flags, rlimits,                                      permittedCapabilities, effectiveCapabilities,                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,                                      NULL, NULL, NULL);  if (pid > 0) {      // The zygote process checks whether the child process has died or not.      ALOGI("System server process %d has been created", pid);      gSystemServerPid = pid;      // There is a slight window that the system server process has crashed      // but it went unnoticed because we haven't published its pid yet. So      // we recheck here just to make sure that all is well.      int status;      if (waitpid(pid, &status, WNOHANG) == pid) {          ALOGE("System server process %d has died. Restarting Zygote!", pid);          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");      }      // Assign system_server to the correct memory cgroup.      if (!WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) {        ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid);      }  }  return pid;}

SystemServer是一个Java类,从main函数入口分析,主要调用run方法,主要工作是:

  1. 调整时间,如果系统时间比1970还要早,调整到1970年
  2. 设置语言
  3. 调整虚拟机堆内存大小和内存利用率
  4. 初始化Looper为mainLooper
  5. 装载库libandroid_server.so
  6. 初始化系统Context
  7. 创建SystemServiceManager负责系统Service启动
  8. 创建和启动Java服务
  9. 调用Looper.loop(),进入处理消息的循环
public static void main(String[] args) {    new SystemServer().run();}public SystemServer() {    // Check for factory test mode.    mFactoryTestMode = FactoryTest.getMode();    // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot    mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));}private void run() {    try {        traceBeginAndSlog("InitBeforeStartServices");        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {            Slog.w(TAG, "System clock is before 1970; setting to 1970.");            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);        }        String timezoneProperty =  SystemProperties.get("persist.sys.timezone");        if (timezoneProperty == null || timezoneProperty.isEmpty()) {            Slog.w(TAG, "Timezone not set; setting to GMT.");            SystemProperties.set("persist.sys.timezone", "GMT");        }        if (!SystemProperties.get("persist.sys.language").isEmpty()) {            final String languageTag = Locale.getDefault().toLanguageTag();            SystemProperties.set("persist.sys.locale", languageTag);            SystemProperties.set("persist.sys.language", "");            SystemProperties.set("persist.sys.country", "");            SystemProperties.set("persist.sys.localevar", "");        }        // The system server should never make non-oneway calls        Binder.setWarnOnBlocking(true);        // Here we go!        Slog.i(TAG, "Entered the Android system server!");        int uptimeMillis = (int) SystemClock.elapsedRealtime();        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);        if (!mRuntimeRestart) {            MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);        }        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());        // Mmmmmm... more memory!        VMRuntime.getRuntime().clearGrowthLimit();        // The system server has to run all of the time, so it needs to be        // as efficient as possible with its memory usage.        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);        // Some devices rely on runtime fingerprint generation, so make sure        // we've defined it before booting further.        Build.ensureFingerprintProperty();        // Within the system server, it is an error to access Environment paths without        // explicitly specifying a user.        Environment.setUserRequired(true);        // Within the system server, any incoming Bundles should be defused        // to avoid throwing BadParcelableException.        BaseBundle.setShouldDefuse(true);        // Ensure binder calls into the system always run at foreground priority.        BinderInternal.disableBackgroundScheduling(true);        // Increase the number of binder threads in system_server        BinderInternal.setMaxThreads(sMaxBinderThreads);        // Prepare the main looper thread (this thread).        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);        android.os.Process.setCanSelfBackground(false);        Looper.prepareMainLooper();        // Initialize native services.        System.loadLibrary("android_servers");        // Check whether we failed to shut down last time we tried.        // This call may not return.        performPendingShutdown();        // Initialize the system context.        createSystemContext();        // Create the system service manager.        mSystemServiceManager = new SystemServiceManager(mSystemContext);        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);        // Prepare the thread pool for init tasks that can be parallelized        SystemServerInitThreadPool.get();    } finally {        traceEnd();  // InitBeforeStartServices    }    // Start services.    try {        traceBeginAndSlog("StartServices");        startBootstrapServices();        startCoreServices();        startOtherServices();        SystemServerInitThreadPool.shutdown();    } catch (Throwable ex) {        Slog.e("System", "******************************************");        Slog.e("System", "************ Failure starting system services", ex);        throw ex;    } finally {        traceEnd();    }    // For debug builds, log event loop stalls to dropbox for analysis.    if (StrictMode.conditionallyEnableDebugLogging()) {        Slog.i(TAG, "Enabled StrictMode for system server main thread.");    }    if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {        int uptimeMillis = (int) SystemClock.elapsedRealtime();        MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);        final int MAX_UPTIME_MILLIS = 60 * 1000;        if (uptimeMillis > MAX_UPTIME_MILLIS) {            Slog.wtf(SYSTEM_SERVER_TIMING_TAG,                    "SystemServer init took too long. uptimeMillis=" + uptimeMillis);        }    }    // Loop forever.    Looper.loop();    throw new RuntimeException("Main thread loop unexpectedly exited");}
Java服务

7.1 ActivityManagerService启动

AMS在SystemServer的startBootstrapServices中启动,主要是创建了一个Lifecycle对象创建AMS。
创建AMS后会调用AMS的start方法。setSystemServiceManager方法是把AMS纳入SystemServerManager的管理。
在AMS的构造函数中初始化了很多变量和一些服务,如果管理广播的队列、电池和CPU等相关服务,服务会在start方法中启动,并等待启动完成。
最后,调用AMS的systemReady方法完成初始化,在SystemReady中启动桌面。

// Activity manager runs the show.traceBeginAndSlog("StartActivityManager");mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);traceEnd();
public static final class Lifecycle extends SystemService {    private final ActivityManagerService mService;    public Lifecycle(Context context) {        super(context);        mService = new ActivityManagerService(context);    }    @Override    public void onStart() {        mService.start();    }    @Override    public void onCleanupUser(int userId) {        mService.mBatteryStatsService.onCleanupUser(userId);    }    public ActivityManagerService getService() {        return mService;    }}

systemReady在SystemServer的startOtherServices的最后被调用,主要是动作是标记和等待各个服务启动完成如等待PMS启动结束,接着启动SystemUI和启动HomeActivity。在Android N之后引入DirectBoot,DirectBoot是一种安全模式,是开机完成但用户还没有解锁的时候处于的一种运行环境。

mActivityManagerService.systemReady(() -> {    Slog.i(TAG, "Making services ready");    traceBeginAndSlog("StartActivityManagerReadyPhase");    mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);    traceEnd();    traceBeginAndSlog("StartObservingNativeCrashes");    try {        mActivityManagerService.startObservingNativeCrashes();    } catch (Throwable e) {        reportWtf("observing native crashes", e);    }    traceEnd();    // No dependency on Webview preparation in system server. But this should    // be completed before allowring 3rd party    final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";    Future<?> webviewPrep = null;    if (!mOnlyCore) {        webviewPrep = SystemServerInitThreadPool.get().submit(() -> {            Slog.i(TAG, WEBVIEW_PREPARATION);            TimingsTraceLog traceLog = new TimingsTraceLog(                    SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);            traceLog.traceBegin(WEBVIEW_PREPARATION);            ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");            mZygotePreload = null;            mWebViewUpdateService.prepareWebViewInSystemServer();            traceLog.traceEnd();        }, WEBVIEW_PREPARATION);    }    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {        traceBeginAndSlog("StartCarServiceHelperService");        mSystemServiceManager.startService(CarServiceHelperService.class);        traceEnd();    }        traceBeginAndSlog("StartSystemUI");    try {        startSystemUi(context, windowManagerF);    } catch (Throwable e) {        reportWtf("starting System UI", e);    }    traceEnd();        ...    traceBeginAndSlog("StartWatchdog");    Watchdog.getInstance().start();    traceEnd();    // Wait for all packages to be prepared    mPackageManagerService.waitForAppDataPrepared();    // It is now okay to let the various system services start their third party code...    traceBeginAndSlog("PhaseThirdPartyAppsCanStart");    // confirm webview completion before starting 3rd party    if (webviewPrep != null) {        ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);    }    mSystemServiceManager.startBootPhase(            SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);    traceEnd();     ...    traceBeginAndSlog("MakeTelephonyRegistryReady");    try {        if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();    } catch (Throwable e) {        reportWtf("Notifying TelephonyRegistry running", e);    }    traceEnd();        traceBeginAndSlog("MakeMediaRouterServiceReady");    try {        if (mediaRouterF != null) mediaRouterF.systemRunning();    } catch (Throwable e) {        reportWtf("Notifying MediaRouterService running", e);    }    traceEnd();        traceBeginAndSlog("MakeMmsServiceReady");    try {        if (mmsServiceF != null) mmsServiceF.systemRunning();    } catch (Throwable e) {        reportWtf("Notifying MmsService running", e);    }    traceEnd();    traceBeginAndSlog("MakeNetworkScoreServiceReady");    try {        if (networkScoreF != null) networkScoreF.systemRunning();    } catch (Throwable e) {        reportWtf("Notifying NetworkScoreService running", e);    }    traceEnd();        traceBeginAndSlog("IncidentDaemonReady");    try {        // TODO: Switch from checkService to getService once it's always        // in the build and should reliably be there.        final IIncidentManager incident = IIncidentManager.Stub.asInterface(                ServiceManager.checkService("incident"));        if (incident != null) incident.systemRunning();    } catch (Throwable e) {        reportWtf("Notifying incident daemon running", e);    }    traceEnd();}, BOOT_TIMINGS_TRACE_LOG);

AMS初始化在启动完成后,在锁屏界面Keyguard绘制完成后(finishKeyguardDrawn),然后调用WindowManagerService的enableScreenAfterBoot,WMS会接着调用performEnableScreen通知SurfaceFlinger关闭开机动画,接着WMS调用AMS的bootAnimationComplete通知AMS开机动画结束,AMS最后通过调用finishBooting设置属性sys.boot_complete通知系统开机完成,可以执行属性sys.boot_complete设置之后的任务

private void performEnableScreen() {    synchronized(mWindowMap) {        try {            IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");            if (surfaceFlinger != null) {                Slog.i(TAG_WM, "******* 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);                data.recycle();                if (mWindowManagerDebugger.WMS_DEBUG_ENG) {                    Slog.d(TAG, "Tell SurfaceFlinger finish boot animation");                }            }        } catch (RemoteException ex) {            Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");        }        mDisplayEnabled = true;        mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);    }    try {        mActivityManager.bootAnimationComplete();    } catch (RemoteException e) {    }    mPolicy.enableScreenAfterBoot();    updateRotationUnchecked(false, false);}
final void finishBooting() {    synchronized (this) {        if (!mBootAnimationComplete) {            mCallFinishBooting = true;            return;        }        mCallFinishBooting = false;    }    // Let system services know.    mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);    synchronized (this) {        SystemProperties.set("sys.boot_completed", "1");    }}

WMS与SurfaceFlingerBinder进行Binder通信的协议:

class BnSurfaceComposer: public BnInterface {public:    enum {        // Note: BOOT_FINISHED must remain this value, it is called from        // Java by ActivityManagerService.        BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,        CREATE_CONNECTION,        UNUSED, // formerly CREATE_GRAPHIC_BUFFER_ALLOC        CREATE_DISPLAY_EVENT_CONNECTION,        CREATE_DISPLAY,        DESTROY_DISPLAY,        GET_BUILT_IN_DISPLAY,        SET_TRANSACTION_STATE,        AUTHENTICATE_SURFACE,        GET_SUPPORTED_FRAME_TIMESTAMPS,        GET_DISPLAY_CONFIGS,        GET_ACTIVE_CONFIG,        SET_ACTIVE_CONFIG,        CONNECT_DISPLAY,        CAPTURE_SCREEN,        CLEAR_ANIMATION_FRAME_STATS,        GET_ANIMATION_FRAME_STATS,        SET_POWER_MODE,        GET_DISPLAY_STATS,        GET_HDR_CAPABILITIES,        GET_DISPLAY_COLOR_MODES,        GET_ACTIVE_COLOR_MODE,        SET_ACTIVE_COLOR_MODE,        ENABLE_VSYNC_INJECTIONS,        INJECT_VSYNC,        CREATE_SCOPED_CONNECTION    };    virtual status_t onTransact(uint32_t code, const Parcel& data,            Parcel* reply, uint32_t flags = 0);};
class BpSurfaceComposer : public BpInterface{public:    explicit BpSurfaceComposer(const sp& impl)        : BpInterface(impl)    {    }    virtual ~BpSurfaceComposer();    virtual void bootFinished()    {        Parcel data, reply;        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);    }}

可以看到WMS通过binder通信,调用IBinder.FIRST_CALL_TRANSACTION函数,也就是android.ui.ISurfaceComposer的BOOT_FINISHED对应的函数bootFinished(),SurfaceFlinger是继承BpSurfaceComposer的,所以最后调用的是SurfaceFlinger::bootFinished(),通过设置属性service.bootanim.exit标记开机动画结束

void SurfaceFlinger::bootFinished(){    if (mStartPropertySetThread->join() != NO_ERROR) {        ALOGE("Join StartPropertySetThread failed!");    }    const nsecs_t now = systemTime();    const nsecs_t duration = now - mBootTime;    ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );    // wait patiently for the window manager death    const String16 name("window");    sp window(defaultServiceManager()->getService(name));    if (window != 0) {        window->linkToDeath(static_cast(this));    }    if (mVrFlinger) {      mVrFlinger->OnBootFinished();    }    // 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.    property_set("service.bootanim.exit", "1");    const int LOGTAG_SF_STOP_BOOTANIM = 60110;    LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,                   ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));    sp readProperties = new LambdaMessage([&]() {        readPersistentProperties();    });    postMessageAsync(readProperties);}

7.2 PackageManagerService启动

PMS是在SystemServer的startBootstrapServices中启动,启动时构建一个PMS实例,初始化相关服务,主要的动作有扫描app目录包括system/app、system/priv-app、vendor/app等,首次启动会调用DexManager对获取到的Package进行load操作,主要是通过SCAN_FIRST_BOOT_OR_UPGRADE这个scanFlag进行区分,而判断设备是否是第一次启动是通过判断文件data/system/packages.xml是否存在进行判断

traceBeginAndSlog("StartPackageManagerService");mPackageManagerService = PackageManagerService.main(mSystemContext, installer,        mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);mFirstBoot = mPackageManagerService.isFirstBoot();mPackageManager = mSystemContext.getPackageManager();traceEnd();
public static PackageManagerService main(Context context, Installer installer,        boolean factoryTest, boolean onlyCore) {    // Self-check for initial settings.    PackageManagerServiceCompilerMapping.checkProperties();    PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore);    m.enableSystemUserPackages();    ServiceManager.addService("package", m);    final PackageManagerNative pmn = m.new PackageManagerNative();    ServiceManager.addService("package_native", pmn);    return m;}

首次开机和非首次开机区别就在于扫描app目录时,首次开机做了dex2ota的动作,相对来说就要较非首次开机耗时

// Set flag to monitor and not change apk file paths when scanning install directories.int scanFlags = SCAN_BOOTING | SCAN_INITIAL;if (mIsUpgrade || mFirstBoot) {    scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;}

PMS的systemReady调用在SystemServer的startOtherServices的最后AMS的systemReady调用之前,也就是说PSM的初始化需要先于AMS,PMS标记systemReady主要是使UserManager和InstallerService等服务标记为systemReady

@Overridepublic void systemReady() {    enforceSystemOrRoot("Only the system can claim the system is ready");    mSystemReady = true;    final ContentResolver resolver = mContext.getContentResolver();    ContentObserver co = new ContentObserver(mHandler) {        @Override        public void onChange(boolean selfChange) {            mEphemeralAppsDisabled = (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||                            (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);        }    };    mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global                    .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),            false, co, UserHandle.USER_SYSTEM);    mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global                    .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);    co.onChange(true);     // Disable any carrier apps. We do this very early in boot to prevent the apps from being    // disabled after already being started.    CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,            mContext.getContentResolver(), UserHandle.USER_SYSTEM);     // Read the compatibilty setting when the system is ready.    boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(            mContext.getContentResolver(),            android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;    PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);    if (DEBUG_SETTINGS) {        Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);    }    int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;    synchronized (mPackages) {        ArrayList removed = new ArrayList();        for (int i=0; i 0) {                for (int r=0; r

8. Launcher启动介绍

8.1SystemUI启动

SystemUI在AMS执行systemReady时启动,主要是通过Intent启动包名为com.android.systemui组件名为SystemUIService的服务,然后通过调用WindowManager的onSystemUiStarted方法调用KeyguardService启动锁屏服务。SystemUI启动成功后表示系统的通知栏和导航栏已经初始化成功,接下来就是启动Launcher

traceBeginAndSlog("StartSystemUI");try {    startSystemUi(context, windowManagerF);} catch (Throwable e) {    reportWtf("starting System UI", e);}traceEnd();
static final void startSystemUi(Context context, WindowManagerService windowManager) {    Intent intent = new Intent();    intent.setComponent(new ComponentName("com.android.systemui",                "com.android.systemui.SystemUIService"));    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);    //Slog.d(TAG, "Starting service: " + intent);    context.startServiceAsUser(intent, UserHandle.SYSTEM);    windowManager.onSystemUiStarted();}

8.2Launcher启动

Launcher的启动在AMS的最后,通过startHomeActivityLocked把启动Launcher的Activity并将其置于Activity栈顶,然后通过resumeFocusedStackTopActivityLocked将栈顶的Activity显示到界面上,launcher的启动就已经完成了

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {    traceLog.traceBegin("PhaseActivityManagerReady");    synchronized(this) {        if (mSystemReady) {            // If we're done calling all the receivers, run the next "boot phase" passed in            // by the SystemServer            if (goingCallback != null) {                goingCallback.run();            }            return;        }        mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);        mAssistUtils = new AssistUtils(mContext);        mVrController.onSystemReady();        // Make sure we have the current profile info, since it is needed for security checks.        mUserController.onSystemReady();        mRecentTasks.onSystemReadyLocked();        mAppOpsService.systemReady();        mSystemReady = true;    }    try {        sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(                ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))                .getSerial();    } catch (RemoteException e) {}    ArrayList procsToKill = null;    synchronized(mPidsSelfLocked) {        for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {            ProcessRecord proc = mPidsSelfLocked.valueAt(i);            if (!isAllowedWhileBooting(proc.info)){                if (procsToKill == null) {                    procsToKill = new ArrayList();                }                procsToKill.add(proc);            }        }    }    synchronized(this) {        if (procsToKill != null) {            for (int i=procsToKill.size()-1; i>=0; i--) {                ProcessRecord proc = procsToKill.get(i);                Slog.i(TAG, "Removing system update proc: " + proc);                removeProcessLocked(proc, true, false, "system update done");            }        }        // Now that we have cleaned up any update processes, we        // are ready to start launching real processes and know that        // we won't trample on them any more.        mProcessesReady = true;    }    Slog.i(TAG, "System now ready");    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,        SystemClock.uptimeMillis());    ...    traceLog.traceBegin("ActivityManagerStartApps");    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,            Integer.toString(currentUserId), currentUserId);    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,            Integer.toString(currentUserId), currentUserId);    mSystemServiceManager.startUser(currentUserId);    synchronized (this) {        // Only start up encryption-aware persistent apps; once user is        // unlocked we'll come back around and start unaware apps       startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);        // Start up initial activity.        mBooting = true;        // Enable home activity for system user, so that the system can always boot. We don't        // do this when the system user is not setup since the setup wizard should be the one        // to handle home activity in this case.        if (UserManager.isSplitSystemUser() &&                Settings.Secure.getInt(mContext.getContentResolver(),                     Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {            ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);            try {                AppGlobals.getPackageManager().setComponentEnabledSetting(cName,                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,                        UserHandle.USER_SYSTEM);            } catch (RemoteException e) {                throw e.rethrowAsRuntimeException();            }        }        startHomeActivityLocked(currentUserId, "systemReady");        try {            if (AppGlobals.getPackageManager().hasSystemUidErrors()) {                Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"                        + " data partition or your device will be unstable.");                mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();            }        } catch (RemoteException e) {        }        if (!Build.isBuildConsistent()) {            Slog.e(TAG, "Build fingerprint is not consistent, warning user");            mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();        }        long ident = Binder.clearCallingIdentity();        try {            Intent intent = new Intent(Intent.ACTION_USER_STARTED);            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY                    | Intent.FLAG_RECEIVER_FOREGROUND);            intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);            broadcastIntentLocked(null, null, intent,                    null, null, 0, null, null, null, AppOpsManager.OP_NONE,                    null, false, false, MY_PID, SYSTEM_UID,                    currentUserId);            intent = new Intent(Intent.ACTION_USER_STARTING);            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);            intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);            broadcastIntentLocked(null, null, intent,                    null, new IIntentReceiver.Stub() {                        @Override                        public void performReceive(Intent intent, int resultCode, String data,                                Bundle extras, boolean ordered, boolean sticky, int sendingUser)                                throws RemoteException {                        }                    }, 0, null, null,                    new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,                    null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);        } catch (Throwable t) {            Slog.wtf(TAG, "Failed sending first user broadcasts", t);        } finally {            Binder.restoreCallingIdentity(ident);        }        mStackSupervisor.resumeFocusedStackTopActivityLocked();        mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);        traceLog.traceEnd(); // ActivityManagerStartApps        traceLog.traceEnd(); // PhaseActivityManagerReady    }}
boolean startHomeActivityLocked(int userId, String reason) {    if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL            && mTopAction == null) {        // We are running in factory test mode, but unable to find        // the factory test app, so just sit around displaying the        // error message and don't try to start anything.        return false;    }    Intent intent = getHomeIntent();    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);    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.instr == null) {            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);            final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);            // For ANR debugging to verify if the user activity is the one that actually launched.            final String myReason = reason + ":" + userId + ":" + resolvedUserId;            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);        }    } else {        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());    }    return true;}
Intent getHomeIntent() {    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);    intent.setComponent(mTopComponent);    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {        intent.addCategory(Intent.CATEGORY_HOME);    }    return intent;}

9. Log抓取与分析方法

开机时间主要分析kernel log、events log、logcat log

adb shell dmesg > dmesg.txtadb logcat –v threadtime –b events –d > logcat_events.logadb logcat –v threadtime –d *:V > logcat.txt

高通平台分析kernel log:

01-01 13:32:28.012 I/KPI ( 0): Bootloader start count = 2643701-01 13:32:28.012 I/KPI ( 0): Bootloader end count = 19938801-01 13:32:28.012 I/KPI ( 0): Bootloader display count = 10176401-01 13:32:28.012 I/KPI ( 0): Bootloader load kernel count = 309701-01 13:32:28.012 I/KPI ( 0): Kernel MPM timestamp = 22687601-01 13:32:28.012 I/KPI ( 0): Kernel MPM Clock frequency = 32768

根据log可以获取以下信息:

  • NHLOS时间:Bootloader start count / Kernel MPM Clock frequency = 26437 / 32768 = 0.807s
  • lk启动时间:(Bootloader end count-Bootloader start count) / Kernel MPM Clock frequency = (199388 - 26437) / 32768 = 5.278s
  • bootloader启动时间:Kernel MPM timestamp / Kernel MPM Clock frequency = 226876 / 32768 = 6.924s

MTK平台分析bootprof:

<< /proc/bootprof >>:----------------------------------------0       BOOT PROF (unit:msec)----------------------------------------      5074        : preloader      2808        : lk (Start->Show logo: 1282)

根据log可以获取以下信息:

  • perloader启动时间是5074ms
  • lk启动时间是2808ms

Events Log分析:

01-01 13:14:19.129 674 674 I boot_progress_start: 1240101-01 13:14:20.135 674 674 I boot_progress_preload_start: 1340801-01 13:14:21.025 675 675 I boot_progress_preload_start: 1429701-01 13:14:21.935 674 674 I boot_progress_preload_end: 1520801-01 13:14:22.519 675 675 I boot_progress_preload_end: 1579201-01 13:14:22.660 1370 1370 I boot_progress_system_run: 1593201-01 13:14:23.152 1370 1370 I boot_progress_pms_start: 1642501-01 13:14:23.794 1370 1370 I boot_progress_pms_system_scan_start: 1706701-01 13:14:25.566 1370 1370 I boot_progress_pms_data_scan_start: 1883801-01 13:14:25.619 1370 1370 I boot_progress_pms_scan_end: 1889201-01 13:14:27.060 1370 1370 I boot_progress_pms_ready: 2033201-01 13:14:29.302 1370 1370 I boot_progress_ams_ready: 2257401-01 13:14:30.472 1370 1455 I boot_progress_enable_screen: 2374401-01 13:14:32.181 492 535 I sf_stop_bootanim: 2545301-01 13:14:32.254 492 492 I sf_frame_dur: [BootAnimation,12,331,3,1,0,1,1]  // 25506 01-01 13:14:32.343 1370 1480 I wm_boot_animation_done: 25616
Kernel part: boot_progress_start = 12401msZygote time: boot_progress_preload_end - boot_progress_preload_start = 15792 - 13408 = 2384msSystem folder Scan time: boot_progress_pms_data_scan_start- boot_progress_pms_system_scan_start = 18838 - 17067 = 1771msData folder scan time: boot_progress_pms_scan_end- boot_progress_pms_data_scan_start = 18892 - 18838 = 54msHome activity start time: boot_progress_enable_screen- boot_progress_ams_ready = 23744 - 22574 = 1170msHome activity idle to Bootanimation finish: sf_frame_dur - boot_progress_enable_screen = 25506 - 23744 = 1762msHome activity idle to SF stop bootanim: sf_stop_bootanim - boot_progress_enable_screen = 25453 - 23744 = 1709msBootanim end time: wm_boot_animation_done - sf_stop_bootanim = 25616 - 25453 = 163ms
Log含义

结束语

到此Android的开机流程就分析完了,比较仓促,有许多不足的地方,开机过程中涉及的许多文件未有说明,如kernel下的defconfig文件,通过配置config文件的宏控,打开某些功能,这些config都会影响到开机的时间,eng、userdebug和user版的差异最大的地方就是这个defconfig的配置,调试的宏控开多了,会大大影响开机时间,曾经试过在eng版本上开机时间长达十分钟的,所以说,要优化开机时间,可以考虑从defconfig文件的配置入手。

了解开机时间流程是为了解Android的整体架构,在此做一下记录,与大家共勉。

更多相关文章

  1. Android:Android(安卓)Studio 优化
  2. android 画图之bitmap(一)
  3. Android(安卓)app ERR_UNKNOWN_URL_SCHEME
  4. Android之Handler的postDelayed()方法的用法
  5. Android(安卓)MediaPlayer 常用方法介绍
  6. someone's android note
  7. Android判断两个时间的间隔
  8. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(二)
  9. 【翻译】Android中的AOP编程

随机推荐

  1. android图形系统详解一:Canvas
  2. Android小项目之二 代码的组织结构
  3. GDB调试Android代码——环境搭建及调试过
  4. Android中Matrix的pre post set方法理解(
  5. java me 与 android 缓冲绘图的一点点认
  6. Android界面导航之拖放框架(Drag and Dro
  7. Android的Aidl安装方法
  8. Android 软件盘之使特定布局保持在软键盘
  9. Android中Textview显示Html,图文混排,支持
  10. Android通过JNI实现与C语言的串口通讯操