---
# System prepended metadata

title: SystemServer
tags: [Android Framework]

---

---
title: 'SystemServer'
disqus: kyleAlien
---

SystemServer
===

## OverView of Content

[TOC]

## SystemServer
SystemServer 是由 init 進程 Fork 出來，而 **AMS、PKMS、PMS、WMS... 等等系統服務 也是由 SystemServer 啟動**
> ![](https://i.imgur.com/XQeXK4j.png)

### SystemServer Context

* SystemServer 啟動 Context 流程
    ```java=
    // /services/java/com/android/server/SystemServer.java

        private void run() {
            try {

                ... 省略部分

                // Initialize the system context.
                createSystemContext();

                ... 省略部分

            } /*省略 catch 部分*/

        }


        private void createSystemContext() {
            // 創建一個 ActivityThread 對象
            ActivityThread activityThread = ActivityThread.systemMain();

            // 取得 系統 Context
            mSystemContext = activityThread.getSystemContext();
            
            // 設定系統主題
            mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
            final Context systemUiContext = activityThread.getSystemUiContext();
            systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
        }

    ```
1. 創建 System 級別的 [**ActivityThread**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java) 對象
    ```java=
    // /core/java/android/app/ActivityThread.java
        public static ActivityThread systemMain() {
            ThreadedRenderer.initForSystemProcess();
            
            // 創建一個 ActivityThread 對象
            ActivityThread thread = new ActivityThread();
            // 繼續分析 attach 方法 (注意傳入參數為 true)
            thread.attach(true, 0);
            return thread;
        }
    ```

2. **ActivityThread `#attach` 函數會創建 Instrumentation 對象**，該對象可以管理 Acitivty
    ```java=
    // ActivityThread.java

        @UnsupportedAppUsage
        private void attach(boolean system, long startSeq) {
            ... 省略部分

            if (!system) {    // 一般 APP
                ... 省略部分 

            } else {        // 系統 
                try {
                    // 創建儀錶板 Instrumentation
                    mInstrumentation = new Instrumentation();
                    mInstrumentation.basicInit(this);
                    
                    // 創 App Context，接著看 createAppContext、getSystemContext 方法
                    ContextImpl context = ContextImpl.createAppContext(
                            this, getSystemContext().mPackageInfo);

                    // 創建 Application 對象
                    // makeApplication 下個小節分析
                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                    mInitialApplication.onCreate();
                } /* 省略 catch */
            }


        }
    ```

3. [**ContextImpl#createAppContext**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ContextImpl.java) 創建 **ContextImpl 對象** (APP 等級)
    ```java=
    // ContextImpl.java

        @UnsupportedAppUsage
        static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
            return createAppContext(mainThread, packageInfo, null);
        }

        static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
                String opPackageName) {
            if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
            ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
                ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);
            context.setResources(packageInfo.getResources());
            context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
                    : CONTEXT_TYPE_NON_UI;
            return context;
        }

    ```
    
4. 取得 ActivityThread 的系統 Context 對象
    ```java=
    // ActivityThread.java

        @Override
        @UnsupportedAppUsage
        public ContextImpl getSystemContext() {
            synchronized (this) {
                if (mSystemContext == null) {
                    mSystemContext = ContextImpl.createSystemContext(this);
                }
                return mSystemContext;
            }
        }

        // 取得 系統 UiContext
        @Override
        public ContextImpl getSystemUiContext() {
            synchronized (this) {
                if (mSystemUiContext == null) {
                    mSystemUiContext = ContextImpl.createSystemUiContext(getSystemContext());
                }
                return mSystemUiContext;
            }
        }
    ```

5. [**ContextImpl#createSystemContext**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ContextImpl.java) 創建系統 **Context (系統等級)**、**LoadedApk** 對象
    ```java=
    // ContextImpl.java

        static ContextImpl createSystemContext(ActivityThread mainThread) {
            // 創建 LoadedApk，用來加載 APK 文件
            LoadedApk packageInfo = new LoadedApk(mainThread);
            
            // 創建 ContextImpl
            ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                    null);
            
            // 設定 Package Resoureces
            context.setResources(packageInfo.getResources());
            context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                    context.mResourcesManager.getDisplayMetrics());
            return context;
        }
    ```
> ![](https://i.imgur.com/Xj60j8n.png)

### ServiceManager - Applicatoin 創建

* 複習前面在 `ActivityThread#attach`函數時，會呼叫 ContextImp 中的 LoadedApk 的 **makeApplication 函數**
    ```java=
    // ActivityThread.java
        @UnsupportedAppUsage
        private void attach(boolean system, long startSeq) {
            ... 省略部分


            if (!system) {
                ... 省略部分

            } else {
                try {
                    // 創建儀錶板 Instrumentation
                    mInstrumentation = new Instrumentation();
                    mInstrumentation.basicInit(this);
                    ContextImpl context = ContextImpl.createAppContext(
                            this, getSystemContext().mPackageInfo);

                    // 創建 Application 對象
                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                    mInitialApplication.onCreate();
                } /* 省略 catch */
            }


        }
    ```
    
* LoadedApk 又是透過 Instrumentation 來創建 Application 對象，並複寫 R 檔(ID 資源檔)
    ```java=
    // ContextImpl.java
    
        static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
            if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
            ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                    null);
            // 設定 Context 資源
            context.setResources(packageInfo.getResources());
            return context;
        }

    // ----------------------------------------------------------
    // LoadedApk.java

        public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            // 一個 LoadedApk 對應一個 mApplication
            if (mApplication != null) {
                return mApplication;
            }

            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

            Application app = null;

            // 若 AndroidManifest.xml 有設定 className 就會使用 User 指定的 Application
            // 取得 String Name 就可以透過反射創建
            String appClass = mApplicationInfo.className;
            if (forceDefaultAppClass || (appClass == null)) {
                // 預設使用 android.app.Application
                appClass = "android.app.Application";
            }

            try {
                java.lang.ClassLoader cl = getClassLoader();
                if (!mPackageName.equals("android")) {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                            "initializeJavaContextClassLoader");
                    initializeJavaContextClassLoader();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                }
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                
                // 透過 Instrumentation 創建 Application 對象
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
                appContext.setOuterContext(app);
            } /*省略 catch*/
            
            
            mActivityThread.mAllApplications.add(app);
            mApplication = app;

            if (instrumentation != null) {
                try {
                    // 呼叫 Application#onCreate 函數 
                    instrumentation.callApplicationOnCreate(app);
                } /*省略 catch*/
            }

            // Rewrite the R 'constants' for all library apks.
            SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
            final int N = packageIdentifiers.size();
            for (int i = 0; i < N; i++) {
                final int id = packageIdentifiers.keyAt(i);
                if (id == 0x01 || id == 0x7f) {
                    continue;
                }

                rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
            }

            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

            return app;
        }
    ```

* 最終透過反射創建 Application (取得 AndroidManifest.xml 設定的 name)
    > ![](https://i.imgur.com/F5FCgrC.png)

    ```java=
    // Instrumentation
        public Application newApplication(ClassLoader cl, String className, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            // 接著看 instantiateApplication
            Application app = getFactory(context.getPackageName())
                    .instantiateApplication(cl, className);
            app.attach(context);
            return app;
        }


    // AppComponectFactory.java
        public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
                @NonNull String className)
                throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            
            // 使用反射創建 Application
            return (Application) cl.loadClass(className).newInstance();
        }
    ```
    > ![](https://i.imgur.com/VgShTp0.png)




### [SystemServiceManager](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/core/java/com/android/server/SystemServiceManager.java) 建構 

* **SystemServiceManager 類是用來管理、啟動系統的服務**，SystemServiceManager 對象建構是在 `SysemServer`#`run` 函數，**在建構完該函數後就會使用它來啟動其他服務**，其中就包括 AMS、WMS、PMS... 等等
    ```java=
    // /android/server/SystemServer.java
    public final class SystemServer implements Dumpable {

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

        private void run() {
            ... 省略部分

            try {
                t.traceBegin("StartServices");

                // 創建 SystemServiceManager 對象
                mSystemServiceManager = new SystemServiceManager(mSystemContext);

                try {
                    t.traceBegin("StartServices");
                    startBootstrapServices(t);    // 引導服務
                    startCoreServices(t);         // 核心服務
                    startOtherServices(t);        // 啟動各種類型的 Services
                } /* 省略服務 */

                ... 省略部分
            } /*省略 catch*/

            ... 省略部分

        }
    }
    ```


### 抽象 [SystemService](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/core/java/com/android/server/SystemService.java) 類 - 服務生命週期

* 這邊所提的 SystemService 是個 **抽象類** (請不要跟上一個搞混~ 雖然他們名子一樣)，會讓其他系統的啟動類繼承 (eg. AMS#Lifecycle 類)，跟系統的 SystemService 不同。

* SystemService 內部有多個參數，可以用來表示 **==服務啟動的過程==，相當於 ++服務啟動的一種生命週期++**，啟動說明請看註解
    ```java=
    // /services/core/java/com/android/server/SystemService.java

    public abstract class SystemService {
        
        // 系統在啟動時的最早階段
        public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
        
        // 異步啟動，等待 Sensor 服務
        public static final int PHASE_WAIT_FOR_SENSOR_SERVICE = 200;

        // 可獲取鎖設置數據
        public static final int PHASE_LOCK_SETTINGS_READY = 480;

        // 系統服務已準備好，可以安心調用核心服務
        // eg. PowerManager or PackageManager
        public static final int PHASE_SYSTEM_SERVICES_READY = 500;

        // 可安心調用特定服務
        public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

        // 接收到這個啟動階段，服務可以廣播 Intent
        public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

        // 可以綁定第三方應用
        // 應用 APP 能將 Binder 調用到服務中
        public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

        // 啟動服務完成，可以跟用戶交互
        public static final int PHASE_BOOT_COMPLETED = 1000;
        
        
        private final Context mContext;
    
        public SystemService(@NonNull Context context) {
            mContext = context;
        }
        
        public abstract void onStart();
        
        ... 省略部分函數
        
    }
    ```


### SystemServiceManager 啟動服務
* 首先先來了解 SystemServiceManager 是如何啟動一個服務的 (**以下舉例 AMS 如何被啟動**)
    ```java=
    // /android/server/SystemServer.java

        // 啟動 AMS 的函數
        private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {

            ... 省略部分

            // Activity manager runs the show.
            // AMS 啟動，分析 startService 方法
            ActivityTaskManagerService atm = mSystemServiceManager.startService(
                    ActivityTaskManagerService.Lifecycle.class).getService();
            mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                    mSystemServiceManager, atm);
            mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
            mActivityManagerService.setInstaller(installer);

            ... 省略部分

            mActivityManagerService.setSystemProcess();

            ... 省略部分

        }
    ```
* Service 啟動流程，是透過 [**SystemServiceManager**](https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/SystemServiceManager.java)#startService 方法來啟動
    1. **啟動 (服務) 類必須繼承抽象的 SystemService 類** (上面說的抽象類)
    2. 呼叫 startService 時使用反射創建對象 (有 Context parameter 的建構函數)
        :::success
        * 呼叫 startService 再建構對象相當於一種延遲加載
        :::
    3. 呼叫實現類的 **onStart 方法** (繼承抽象 SystemService 類)
        ```java=
        // SystemServiceManager.java

            // 快取
            private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();

            public <T extends SystemService> T startService(Class<T> serviceClass) {
                try {
                    final String name = serviceClass.getName();
                    ...
                    // Create the service.

                    // 1. 啟動類必須繼承 SystemService 類
                    if (!SystemService.class.isAssignableFrom(serviceClass)) {
                        throw new RuntimeException("Failed to create " + name
                                + ": service must extend " + SystemService.class.getName());
                    }
                    final T service;
                    try {
                        // 2. 啟動有 Context parameter 的建構函數
                        Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                        service = constructor.newInstance(mContext);
                    } /**
                       * 省略 catch
                       */
                    
                    // 接著分析 startService
                    startService(service);
                    return service;
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                }
            }

            public void startService(@NonNull final SystemService service) {
                // Register it.
                mServices.add(service);
                // Start it.
                long time = SystemClock.elapsedRealtime();
                try {
                    // 呼叫實現類的 onStart 方法
                    // 抽象方法
                    service.onStart();
                } catch (RuntimeException ex) {
                    throw new RuntimeException("Failed to start service " + service.getClass().getName()
                            + ": onStart threw an exception", ex);
                }
                warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
            }
        ```

* UML 關係圖
    > ![](https://i.imgur.com/xoKg0ul.png)


## Appendix & FAQ

:::info
:::

###### tags: `Android Framework`
