天天看點

Android 11 SystemServer源碼分析

SystemServer#main

上篇說過,system_server程序啟動後會調用SystemServer#main方法,SystemServer#main非常的簡單

public static void main(String[] args) {
    new SystemServer().run();
}
           

我們再看SystemServer#run

private void run() {
    try {
        
        ...

        // The system server should never make non-oneway calls
        Binder.setWarnOnBlocking(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();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

        // 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();

        // Call per-process mainline module initialization.
        ActivityThread.initializeMainlineModules();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // Prepare the thread pool for init tasks that can be parallelized
        SystemServerInitThreadPool.start();

        ...

    } finally {
       ...
    }

    // Setup the default WTF handler
    RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf);

    // Start services.
    try {
        startBootstrapServices(t);
        startCoreServices(t);
        startOtherServices(t);
    } catch (Throwable ex) {
        ...
    } finally {
        ...
    }

    ...

    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
           

可以看到run方法的工作主要要以下幾點:

  1. 對Binder進行了一些設定,這個等到之後分析Binder的時候再看;
  2. performPendingShutdown:判斷是否要關機或者重新開機;
  3. createSystemContext:建立系統上下文,這個留到分析Context的時候再看;
  4. 建立ServiceManager
  5. 開啟各種服務,然後進入Looper消息循環

本文主要關注第5點。

performPendingShutdown

private void performPendingShutdown() {
    final String shutdownAction = SystemProperties.get(
            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    if (shutdownAction != null && shutdownAction.length() > 0) {
        boolean reboot = (shutdownAction.charAt(0) == '1');

        ...

        if (不需要關機或重新開機) {
            return;
        }

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    ShutdownThread.rebootOrShutdown(null, reboot, reason);
                }
            }
        };

        // ShutdownThread must run on a looper capable of displaying the UI.
        Message msg = Message.obtain(UiThread.getHandler(), runnable);
        msg.setAsynchronous(true);
        UiThread.getHandler().sendMessage(msg);

    }
}
           

可以看出,主要是根據ShutdownThread.SHUTDOWN_ACTION_PROPERTY屬性值來判斷是否需要關機或重新開機

startBootstrapServices

startBootstrapServices主要是啟動最重要的互相依賴的關鍵性的系統服務,比如ActivityManagerService、PackageManagerService、UserManagerService和PowerManagerService等等。

由于SystemServer啟動的服務非常衆多,我們不可能一下子每個都去了解完,這裡我們隻關注幾個常用的核心服務以及SystemServer的啟動階段即可。後續再去具體分析ActivityManagerService等的具體工作流程。

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {

    // 啟動ActivityManagerService
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();

    // 啟動PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    // 
    mActivityManagerService.initPowerManagement();

    mSystemServiceManager.startService(LightsService.class);
    
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    
    // 啟動PackageManagerService
    try {
        Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    } finally {
        Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
    }

    // 啟動PackageManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
}
           

上面代碼精簡了非常多的代碼,隻保留了一下常見的服務啟動相關代碼。值得注意的是,DisplayManagerService啟動後,SystemServer進入PHASE_WAIT_FOR_DEFAULT_DISPLAY階段。也就是這句

startCoreServices

startCoreServices中啟動了沒有在startBootstrapServices啟動的核心服務

private void startCoreServices(@NonNull TimingsTraceAndSlog t) {

    // Service for system config
    mSystemServiceManager.startService(SystemConfigService.class);

    // Tracks the battery level.  Requires LightService.
    mSystemServiceManager.startService(BatteryService.class);

    // Tracks application usage stats.
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    }

    // Tracks and caches the device state.
    mSystemServiceManager.startService(CachedDeviceStateService.class);

    // Tracks cpu time spent in binder calls
    mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);

    // Tracks time spent in handling messages in handlers.
    mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);

    // Manages apk rollbacks.
    mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS);

    // Service to capture bugreports.
    mSystemServiceManager.startService(BugreportManagerService.class);

    // Serivce for GPU and GPU driver.
    mSystemServiceManager.startService(GpuService.class);
}
           

startCoreServices啟動的服務不多,這裡精簡了log相關代碼。可以看到電池服務、GPU相關服務、BugReport等都在這裡啟動。

startOtherServices

startOtherServices非常龐大,有1400+行代碼,啟動了幾十上百個服務,其中我們比較常見的應該是ConnectivityService、WindowManagerService

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    
    ...

    t.traceBegin("MakeLockSettingsServiceReady");
    if (lockSettings != null) {
        try {
            lockSettings.systemReady();
        } catch (Throwable e) {
            reportWtf("making Lock Settings Service ready", e);
        }
    }
    t.traceEnd();

    
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_LOCK_SETTINGS_READY);
    // 這兩個階段中間什麼也沒有做
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_SYSTEM_SERVICES_READY);

    // Start device specific services
    final String[] classes = mSystemContext.getResources().getStringArray(
            R.array.config_deviceSpecificSystemServices);
    for (final String className : classes) {
        try {
            mSystemServiceManager.startService(className);
        } catch (Throwable e) {
            reportWtf("starting " + className, e);
        }
    }

    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

    
    mActivityManagerService.systemReady(() -> {
        
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
        
        
        try {
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            reportWtf("starting System UI", e);
        }
        

        // Wait for all packages to be prepared
        mPackageManagerService.waitForAppDataPrepared();

        
        // confirm webview completion before starting 3rd party
        if (webviewPrep != null) {
            ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
        }
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

    }, t);

    t.traceEnd(); // startOtherServices
}
           

可以看到在調用lockSettings.systemReady()之後進入了PHASE_LOCK_SETTINGS_READY和PHASE_SYSTEM_SERVICES_READY,這兩個階段什麼都沒有做。

“device specific services”看來應該是一組服務,此處暫不深究。這一組服務啟動後,進入PHASE_DEVICE_SPECIFIC_SERVICES_READY階段。

startOtherServices方法的最後調用了ActivityManagerService#systemReady,并在回調中啟動了SystemUi。跟進一下

public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
    mSystemServiceManager.preSystemReady();
    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;
        }

        ...
    }

    ...

    if (bootingSystemUser) {
        t.traceBegin("startHomeOnAllDisplays");
        mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
        t.traceEnd();
    }

    ...
}
           

可以看到,在調用SystemServiceManager#preSystemReady()就運作了回調,進了PHASE_ACTIVITY_MANAGER_READY階段。随後啟動了SystemUi,這個後續分析SystemUi的時候再深入了解。

另外,在webview就緒之後,進入了PHASE_THIRD_PARTY_APPS_CAN_START階段,可以啟動第三方App了。

值得注意的是,Launcher的啟動也是由這裡開始:

SystemServer的啟動還有最後一個階段,發生在ActivityManagerService#finishBooting方法中

final void finishBooting() {
    
    ...

    // Let system services know.
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED);

    ...

    synchronized (this) {
           
        ...

        // 發送系統啟動完成通知,包括我們熟悉的開機廣播
        mUserController.sendBootCompleted(
                new IIntentReceiver.Stub() {
                    @Override
                    public void performReceive(Intent intent, int resultCode,
                            String data, Bundle extras, boolean ordered,
                            boolean sticky, int sendingUser) {
                        synchronized (ActivityManagerService.this) {
                            mOomAdjuster.mCachedAppOptimizer.compactAllSystem();
                            requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
                        }
                    }
                });
        maybeLogUserspaceRebootEvent();
        mUserController.scheduleStartProfiles();
    }
}
           

至此,系統服務啟動完成。我們熟悉的開機廣播也是在這裡發出的。

SystemServer啟動流程

不同版本的SystemServer啟動流程會有一些差别,比如WatchDog的啟動時機等等。這裡分析的是Android 11中的SystemServer。我們注意到在每個啟動階段都會調用SystemServiceManager#startBootPhase方法,其定義如下:

public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
    ...

    mCurrentPhase = phase;

    Slog.i(TAG, "Starting phase " + mCurrentPhase);
    try {
        t.traceBegin("OnBootPhase_" + phase);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            ...
            service.onBootPhase(mCurrentPhase);
            ...
        }
    } finally {
        t.traceEnd();
    }

    ...
}
           

其主要工作是周遊和調用每個Service的onBootPhase方法,讓系統服務知曉目前啟動階段并可以執行相應的操作。

各個階段的定義位于SystemService.java内:

public abstract class SystemService {

    /*
     * The earliest boot phase the system send to system services on boot.
     */
    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;

    /**
     * After receiving this boot phase, services can obtain lock settings data.
     */
    public static final int PHASE_LOCK_SETTINGS_READY = 480;

    /**
     * After receiving this boot phase, services can safely call into core system services
     * such as the PowerManager or PackageManager.
     */
    public static final int PHASE_SYSTEM_SERVICES_READY = 500;

    /**
     * After receiving this boot phase, services can safely call into device specific services.
     */
    public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

    /**
     * After receiving this boot phase, services can broadcast Intents.
     */
    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

    /**
     * After receiving this boot phase, services can start/bind to third party apps.
     * Apps will be able to make Binder calls into services at this point.
     */
    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

    /**
     * After receiving this boot phase, services can allow user interaction with the device.
     * This phase occurs when boot has completed and the home application has started.
     * System services may prefer to listen to this phase rather than registering a
     * broadcast receiver for {@link android.content.Intent#ACTION_LOCKED_BOOT_COMPLETED}
     * to reduce overall latency.
     */
    public static final int PHASE_BOOT_COMPLETED = 1000;
}
           

PHASE_WAIT_FOR_DEFAULT_DISPLAY: 已啟動ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService等核心引導服務

PHASE_LOCK_SETTINGS_READY:已完成核心服務的啟動,LockSettingsService已經就緒

PHASE_SYSTEM_SERVICES_READY:系統核心服務已經就緒,可以為其他Service提供服務了

PHASE_DEVICE_SPECIFIC_SERVICES_READY:裝置特定服務組已經就緒

PHASE_ACTIVITY_MANAGER_READY:ActivityManagerService就緒,可以發送廣播了

PHASE_THIRD_PARTY_APPS_CAN_START:服務可以啟動或者bind第三方App,App可以通過Binder調用系統服務了

PHASE_BOOT_COMPLETED:開機完成,可以相應使用者互動了。系統服務應該監聽PHASE_BOOT_COMPLETED流程而不是等待ACTION_LOCKED_BOOT_COMPLETED廣播。

總結

SystemServer是系統非常重要的程序,牽涉非常廣泛,但是大部分功能都封裝在對應的Service裡,是以SystemServer.java本身代碼量并不是很多,總體流程也不算很複雜。接下來會深入我們常見的服務,一探究竟。