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方法的工作主要要以下幾點:
- 對Binder進行了一些設定,這個等到之後分析Binder的時候再看;
- performPendingShutdown:判斷是否要關機或者重新開機;
- createSystemContext:建立系統上下文,這個留到分析Context的時候再看;
- 建立ServiceManager
- 開啟各種服務,然後進入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本身代碼量并不是很多,總體流程也不算很複雜。接下來會深入我們常見的服務,一探究竟。