Android原始碼分析 - SystemServer(下)

語言: CN / TW / HK

開篇

本篇以android-11.0.0_r25作為基礎解析

上一篇文章Android原始碼分析 - SystemServer(上)我們分析了SystemServer程序是怎麼被啟動起來的,今天這篇,我們來分析SystemServer程序啟動後做了什麼

main

我們上一章中講到,Zygote程序fork出子程序後,最終呼叫了SystemServer.main方法,SystemServer原始碼在frameworks/base/services/java/com/android/server/SystemServer.java中,我們來看看做了什麼

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

構造方法

非常簡單,就是先new了一個SystemServer物件,然後呼叫它的run方法,我們先看一下構造方法

```java public SystemServer() { //工廠模式 mFactoryTestMode = FactoryTest.getMode();

... //記錄啟動資訊

//記錄是否經歷過重啟
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));

} ```

工廠模式

首先,先從系統屬性中獲取工廠模式級別,有三種屬性:

  • FACTORY_TEST_OFF:正常模式
  • FACTORY_TEST_LOW_LEVEL:低級別工廠模式,在此模式下,很多Service不會啟動
  • FACTORY_TEST_HIGH_LEVEL:高級別工廠模式,此模式與正常模式基本相同,略有區別

它們被定義在frameworks/base/core/java/android/os/FactoryTest.java

run

緊接著便開始執行run方法

```java private void run() { ... //記錄啟動資訊 //如果沒有設定時區,將時區設定為GMT 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", "");
}

//Binder事務發生阻塞時發出警告
Binder.setWarnOnBlocking(true);
//PackageManager相關
PackageItemInfo.forceSafeLabels();
...
//設定虛擬機器庫檔案libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
//清除虛擬機器記憶體增長上限,以獲得更多記憶體
VMRuntime.getRuntime().clearGrowthLimit();
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty();
//設定在訪問環境變數前,需要明確指定使用者
Environment.setUserRequired(true);
//設定標記,當發生BadParcelableException異常時保守處理,不要丟擲異常
BaseBundle.setShouldDefuse(true);
//設定異常跟蹤
Parcel.setStackTraceParceling(true);
//確保Binder呼叫優先順序總為前臺優先順序
BinderInternal.disableBackgroundScheduling(true);
//設定Binder執行緒池最大數量
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);
//以當前執行緒作為MainLooper準備
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
        SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

//載入android_servers.so庫
System.loadLibrary("android_servers");
//標記該程序的堆可分析
initZygoteChildHeapProfiling();
//Debug選項 - 開啟一個執行緒用來監測FD洩漏
if (Build.IS_DEBUGGABLE) {
    spawnFdLeakCheckThread();
}
//檢查上次關機過程中是否失敗
performPendingShutdown();
//初始化System Context
createSystemContext();
//建立並設定一些每個程序啟動時都需要的一些模組 (TelephonyServiceManager, StatsServiceManager)
ActivityThread.initializeMainlineModules();

//建立SystemServiceManager(管理所有的系統Service)
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
        mRuntimeStartElapsedTime, mRuntimeStartUptime);
//將SystemServiceManager作為本地程序Service使用
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//為初始化任務準備執行緒池
SystemServerInitThreadPool.start();
...
//設定預設異常處理程式
RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf);

...
//啟動引導服務
startBootstrapServices(t);
//啟動核心服務
startCoreServices(t);
//啟動其他服務
startOtherServices(t);
...

//嚴格模式初始化虛擬機器策略
StrictMode.initVmDefaults(null);
...
//進入Looper死迴圈,等待Handler事件
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");

} ```

可以看到,run方法主要做了以下工作

  1. 檢查並設定各種引數handler
  2. 建立SystemContext
  3. 建立SystemServiceManager
  4. 啟動服務
  5. Looper迴圈

其中,建立SystemContext這一步是由ContextImpl完成的,等後面分析到的時候在詳細去看,Looper也是,我們將重點放在啟動服務上

啟動服務

啟動服務分為三步,首先是啟動引導服務,其次是啟動核心服務,最後是啟動其他服務,我們先從引導服務開始

由於啟動的服務太多了,我們只介紹一些我們比較熟悉的服務

startBootstrapServices

```java private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { ... //看門狗 final Watchdog watchdog = Watchdog.getInstance(); watchdog.start(); ... final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig"; //讀取系統配置 SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG); ... //Installer服務(實際上是與installd跨程序通訊) Installer installer = mSystemServiceManager.startService(Installer.class); ... //建立 ATMS & AMS ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); ... //電源管理服務,後面有其他服務依賴它,所以需要較早啟動 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); ... mActivityManagerService.initPowerManagement(); ... //燈光服務 mSystemServiceManager.startService(LightsService.class); ... //顯示管理服務 mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); ... //階段100 mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

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

//捕獲dex load行為
SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);
//是否首次啟動
mFirstBoot = mPackageManagerService.isFirstBoot();
//獲取PMS
mPackageManager = mSystemContext.getPackageManager();
...
//使用者管理服務
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
...
//初始化屬性快取
AttributeCache.init(mSystemContext);
...
//註冊各種系統服務
mActivityManagerService.setSystemProcess();
...
//使用AMS完成看門狗的設定,並監聽重新啟動
watchdog.init(mSystemContext, mActivityManagerService);
...
//設定排程策略
mDisplayManagerService.setupSchedulerPolicies();
...
//在單獨執行緒中啟動感測器服務
mSensorServiceStart = SystemServerInitThreadPool.submit(() -> {
    TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
    traceLog.traceBegin(START_SENSOR_SERVICE);
    startSensorService();
    traceLog.traceEnd();
}, START_SENSOR_SERVICE);
...

} ```

startCoreServices

java private void startCoreServices(@NonNull TimingsTraceAndSlog t) { ... //電池電量服務,依賴LightsService mSystemServiceManager.startService(BatteryService.class); ... //應用統計服務 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); ... }

startOtherServices

```java private void startOtherServices(@NonNull TimingsTraceAndSlog t) { ... //AccountManagerService - 賬戶管理 mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS); ... //ContentService - 內容服務 mSystemServiceManager.startService(CONTENT_SERVICE_CLASS); ... //載入SettingProvider mActivityManagerService.installSystemProviders(); ... //DropBox日誌服務 mSystemServiceManager.startService(DropBoxManagerService.class); ... //震動服務 vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator); ... //時鐘/鬧鐘服務 mSystemServiceManager.startService(new AlarmManagerService(context)); //輸入服務 inputManager = new InputManagerService(context); ... //等待感測器服務準備完畢 ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE); mSensorServiceStart = null; //啟動WindowManagerService wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager); ServiceManager.addService(Context.WINDOW_SERVICE, wm, / allowIsolated= / false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); ServiceManager.addService(Context.INPUT_SERVICE, inputManager, / allowIsolated= / false, DUMP_FLAG_PRIORITY_CRITICAL); ... mActivityManagerService.setWindowManager(wm); ... wm.onInitReady(); ... //HIDL services SystemServerInitThreadPool.submit(() -> { startHidlServices(); }, START_HIDL_SERVICES); ... //關聯WMS,啟動輸入服務 inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback()); inputManager.start(); ... mDisplayManagerService.windowManagerAndInputReady(); ... //有藍芽功能且非低階工廠模式,啟動藍芽服務 if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) { ... } else if (!context.getPackageManager().hasSystemFeature (PackageManager.FEATURE_BLUETOOTH)) { ... } else { mSystemServiceManager.startService(BluetoothService.class); } ... //輸入法/無障礙服務 if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) { if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) { mSystemServiceManager.startService( MultiClientInputMethodManagerService.Lifecycle.class); } else { mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class); } mSystemServiceManager.startService(ACCESSIBILITY_MANAGER_SERVICE_CLASS); }

wm.displayReady();

//儲存相關服務
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
    if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
        mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
        storageManager = IStorageManager.Stub.asInterface(
                    ServiceManager.getService("mount"));
        mSystemServiceManager.startService(STORAGE_STATS_SERVICE_CLASS);
    }
}

//UIMode服務(夜間模式,駕駛模式等)
mSystemServiceManager.startService(UiModeManagerService.class);
...
//執行磁碟清理工作,釋放磁碟空間
mPackageManagerService.performFstrimIfNeeded();

if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
    ...
    final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
    ...
    if (hasPdb || OemLockService.isHalPresent()) {
        //OEM鎖服務
        mSystemServiceManager.startService(OemLockService.class);
    }
    ...
    if (!isWatch) {
        //狀態列管理服務
        statusBar = new StatusBarManagerService(context);
        ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
    }

    //網路相關服務
    ConnectivityModuleConnector.getInstance().init(context);
    NetworkStackClient.getInstance().init();
    networkManagement = NetworkManagementService.create(context);
    ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
    ipSecService = IpSecService.create(context, networkManagement);
    ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);

    //文字服務
    mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
    mSystemServiceManager
                .startService(TextClassificationManagerService.Lifecycle.class);

    //網路相關服務
    mSystemServiceManager.startService(NetworkScoreService.Lifecycle.class);
    networkStats = NetworkStatsService.create(context, networkManagement);
    ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
    networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
                networkManagement);
    ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_WIFI)) {
        mSystemServiceManager.startServiceFromJar(
                WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
        mSystemServiceManager.startServiceFromJar(
                WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
    }
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_WIFI_RTT)) {
        mSystemServiceManager.startServiceFromJar(
                WIFI_RTT_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
    }
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_WIFI_AWARE)) {
        mSystemServiceManager.startServiceFromJar(
                WIFI_AWARE_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
    }
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_WIFI_DIRECT)) {
        mSystemServiceManager.startServiceFromJar(
                WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
    }
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_LOWPAN)) {
        mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
    }
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
            mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
        mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
    }
    connectivity = new ConnectivityService(
                context, networkManagement, networkStats, networkPolicy);
    ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity,
                /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
    networkPolicy.bindConnectivityManager(connectivity);
    ...
    //系統更新服務
    ServiceManager.addService(Context.SYSTEM_UPDATE_SERVICE,
                new SystemUpdateManagerService(context));
    ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
                new UpdateLockService(context));
    //通知服務
    mSystemServiceManager.startService(NotificationManagerService.class);
    SystemNotificationChannels.removeDeprecated(context);
    SystemNotificationChannels.createAll(context);
    notification = INotificationManager.Stub.asInterface(
            ServiceManager.getService(Context.NOTIFICATION_SERVICE));
    ...
    //位置服務
    mSystemServiceManager.startService(LocationManagerService.Lifecycle.class);
    ...
    //牆紙服務
    if (context.getResources().getBoolean(R.bool.config_enableWallpaperService)) {
        mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
    } else {
        ...
    }
    //音訊服務
    if (!isArc) {
        mSystemServiceManager.startService(AudioService.Lifecycle.class);
    } else {
        String className = context.getResources()
                .getString(R.string.config_deviceSpecificAudioService);
        mSystemServiceManager.startService(className + "$Lifecycle");
    }
    ...
    //ADB服務
    mSystemServiceManager.startService(ADB_SERVICE_CLASS);
    //USB服務
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
            || mPackageManager.hasSystemFeature(
            PackageManager.FEATURE_USB_ACCESSORY)
            || isEmulator) {
        mSystemServiceManager.startService(USB_SERVICE_CLASS);
    }
    //微件(小元件)服務
    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)
            || context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) {
        mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
    }
    ...
    //Android10新增,用於報告來自執行時模組的資訊
    ServiceManager.addService("runtime", new RuntimeService(context));
    ...
    //App後臺Dex優化
    BackgroundDexOptService.schedule(context);
    ...
}
...
//相機服務
if (!disableCameraService) {
    mSystemServiceManager.startService(CameraServiceProxy.class);
}
//進入安全模式
if (safeMode) {
    mActivityManagerService.enterSafeMode();
}

//簡訊服務
mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
...
//剪貼簿服務
mSystemServiceManager.startService(ClipboardService.class);
...

//呼叫各大服務的systemReady方法

vibrator.systemReady();
lockSettings.systemReady();

//階段480
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_LOCK_SETTINGS_READY);
//階段500
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_SYSTEM_SERVICES_READY);

wm.systemReady();
...
//手動更新Context Configuration
final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
DisplayMetrics metrics = new DisplayMetrics();
context.getDisplay().getMetrics(metrics);
context.getResources().updateConfiguration(config, metrics);

final Theme systemTheme = context.getTheme();
if (systemTheme.getChangingConfigurations() != 0) {
    systemTheme.rebase();
}

mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
...
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(safeMode, mOnlyCore);

mSystemServiceManager.setSafeMode(safeMode);

//階段520
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
...
//最後執行AMS.systemReady
mActivityManagerService.systemReady(() -> {
    //階段550
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
    ...
    //階段600
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    ...
}, t);

} ```

服務的啟動是分階段完成的,從0-100-480-500-520-550-600-1000,最後的階段1000,是在AMS呼叫finishBooting方法後進入

可以看到,啟動的服務非常之多,不可能全看得完,其中最重要的幾個:ActivityManagerServiceWindowManagerServicePackageManagerServiceInputManagerService,後面我們會慢慢看過去,在此之前,我們還是先看看服務啟動的方式

SystemServiceManager

絕大部分的服務是通過SystemServiceManager啟動的,它的原始碼路徑為frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

startService

我們來看看這個類裡的啟動服務方法

這個類中有三個方法用於啟動Serivce,分別是:

  • public SystemService startService(String className)
  • public SystemService startServiceFromJar(String className, String path)
  • public <T extends SystemService> T startService(Class<T> serviceClass)
  • public void startService(@NonNull final SystemService service)

實際上最後都是呼叫了最後一個方法

先看引數為StringstartService方法

java public SystemService startService(String className) { final Class<SystemService> serviceClass = loadClassFromLoader(className, this.getClass().getClassLoader()); return startService(serviceClass); }

java private static Class<SystemService> loadClassFromLoader(String className, ClassLoader classLoader) { try { return (Class<SystemService>) Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { ... } }

實際上就是通過反射拿到類名對應的Class,再呼叫Class為參的startService方法

startServiceFromJar實際上也是一樣,只不過是先通過PathClassLoader載入了jar而已

java public SystemService startServiceFromJar(String className, String path) { PathClassLoader pathClassLoader = mLoadedPaths.get(path); if (pathClassLoader == null) { // NB: the parent class loader should always be the system server class loader. // Changing it has implications that require discussion with the mainline team. pathClassLoader = new PathClassLoader(path, this.getClass().getClassLoader()); mLoadedPaths.put(path, pathClassLoader); } final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader); return startService(serviceClass); }

接著我們看看Class為引數的startService方法

```java public T startService(Class serviceClass) { final String name = serviceClass.getName();

// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
    throw new RuntimeException("Failed to create " + name
            + ": service must extend " + SystemService.class.getName());
}
final T service;
try {
    Constructor<T> constructor = serviceClass.getConstructor(Context.class);
    service = constructor.newInstance(mContext);
} catch (...) {
    ...
}

startService(service);
return service;

} ```

看函式泛型我們就可以知道,這個方法只接受SystemService的子類,並且在方法的開頭,還使用了isAssignableFrom方法做了型別校驗,避免通過String反射獲取的ClassSystemService的子類

之後的邏輯也很簡單,反射例項化物件,然後呼叫另一個以SystemService物件為引數的過載方法

java public void startService(@NonNull final SystemService service) { mServices.add(service); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } }

這個方法會將SystemService物件加入一個List中,然後呼叫它的onStart方法,通知SystemService自行處理啟動

startBootPhase

因為各種服務之間是存在依賴關係的,所以Android將服務的啟動劃分了8個階段:0-100-480-500-520-550-600-1000,而startBootPhase方法便是用來通知各個服務進行到哪一階段了

```java public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase;

final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
    final SystemService service = mServices.get(i);
    service.onBootPhase(mCurrentPhase);
}

if (phase == SystemService.PHASE_BOOT_COMPLETED) {
    SystemServerInitThreadPool.shutdown();
}

} ```

每進入到一個階段,便會呼叫Service List中所有SystemServiceonBootPhase方法,通知SystemService階段變換,而當階段達到1000 (PHASE_BOOT_COMPLETED) 時,就代表著所有的服務都已準備完畢,關閉SystemServerInitThreadPool執行緒池

ServiceManager

當服務被創建出來後,會呼叫ServiceManager.addService方法新增服務,以供其他地方使用這些服務

addService有三個過載,最終呼叫的為:

java public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) { try { getIServiceManager().addService(name, service, allowIsolated, dumpPriority); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } }

```java private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; }

// Find the service manager
sServiceManager = ServiceManagerNative
        .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;

} ```

```java public static IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; }

// ServiceManager is never local
return new ServiceManagerProxy(obj);

} ```

```java class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { mRemote = remote; mServiceManager = IServiceManager.Stub.asInterface(remote); }

public IBinder asBinder() {
    return mRemote;
}
...
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
        throws RemoteException {
    mServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
...
private IBinder mRemote;

private IServiceManager mServiceManager;

} ```

從這裡就能看出來ServiceManager實際上是一個單獨的程序,名為servicemanager,它負責管理所有服務,使用了Binder IPC機制,我們呼叫addService方法實際上是呼叫了Binder Proxy的方法,他向/dev/binder中寫入訊息,在servicemanager程序中接收到了這個訊息並處理這個請求

關於Binder機制,我們隨後便會分析它

最終呼叫了frameworks/native/cmds/servicemanager/ServiceManager.cpp中的addService函式

```c++ Status ServiceManager::addService(const std::string& name, const sp& binder, bool allowIsolated, int32_t dumpPriority) { auto ctx = mAccess->getCallingContext(); ... //新增服務 auto entry = mNameToService.emplace(name, Service { .binder = binder, .allowIsolated = allowIsolated, .dumpPriority = dumpPriority, .debugPid = ctx.debugPid, });

auto it = mNameToRegistrationCallback.find(name);
if (it != mNameToRegistrationCallback.end()) {
    for (const sp<IServiceCallback>& cb : it->second) {
        entry.first->second.guaranteeClient = true;
        // permission checked in registerForNotifications
        cb->onRegistration(name, binder);
    }
}

return Status::ok();

} ```

可以看到,最終通過service name和傳過來的binder物件構造出一個Service結構體,並將其儲存至mNameToService這個Map中,以供後面使用

關於程序

SystemServer啟動的服務大多都執行在systemserver程序中,但也有一些例外

譬如Installer服務,便是從init程序單獨fork出了一個installd程序

下面是它的rc檔案,frameworks/native/cmds/installd/installd.rc

service installd /system/bin/installd class main ...

而在SystemServer程序中start的Installer,便是通過binder連線到installd程序提供服務

原始碼路徑frameworks/base/services/core/java/com/android/server/pm/Installer.java

```java @Override public void onStart() { if (mIsolated) { mInstalld = null; } else { connect(); } }

private void connect() { IBinder binder = ServiceManager.getService("installd"); if (binder != null) { try { binder.linkToDeath(new DeathRecipient() { @Override public void binderDied() { Slog.w(TAG, "installd died; reconnecting"); connect(); } }, 0); } catch (RemoteException e) { binder = null; } }

if (binder != null) {
    mInstalld = IInstalld.Stub.asInterface(binder);
    try {
        invalidateMounts();
    } catch (InstallerException ignored) {
    }
} else {
    Slog.w(TAG, "installd not found; trying again");
    BackgroundThread.getHandler().postDelayed(() -> {
        connect();
    }, DateUtils.SECOND_IN_MILLIS);
}

} ```

結束

SystemServer啟動了非常多的服務,並將這些服務新增到了ServiceManager中,我們又從中引申出了Binder機制,我們下一章便開始分析Binder