Android系统启动(三) — SystemServer处理过程

system_server 进程主要是用于创建系统服务,ATMS、AMS、WMS、PMS 都是由它创建的。 具体来说,system_server 进程被创建后,主要做了以下工作:

  • 启动 Binder 线程池,这样就可以与其他进程进行通信;
  • 创建 SystemServiceManager,用于对系统服务进行创建、启动和生命周期管理;
  • 启动各种系统服务;

1 Zygote 处理 system_server 进程

Zygote进程启动过程 中讲到 ,在 ZygoteInit.main 方法中,通过调用 forkSystemServer 方法启动 system_server 进程,一些相关时序图:

Zygote 处理 system_server 进程

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;
    ...
    Runnable caller;
    try {
        ...

        final boolean isPrimaryZygote = 
          zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
        ...

        if (!enableLazyPreload) {
            ...
            preload(bootTimingsTraceLog); // 预加载资源
            ...
        }
				...

        zygoteServer = new ZygoteServer(isPrimaryZygote);

        if (startSystemServer) {
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // 1
            if (r != null) {
                r.run();
                return;
            }
        }

       	...
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        ...
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

    if (caller != null) {
        caller.run();
    }
}

注释 1 处调用 forkSystemServer 方法启动 system_server 进程,ZygoteInit.forkSystemServer 的代码如下所示:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    ...

    /* 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,"
                    + "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs;

    int pid;

    try {
        ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
        try {
            parsedArgs = ZygoteArguments.getInstance(commandBuffer);
        } catch (EOFException e) {
            throw new AssertionError("Unexpected argument error for forking system server", e);
        }
        commandBuffer.close();
        Zygote.applyDebuggerSystemProperty(parsedArgs);
        Zygote.applyInvokeWithSystemProperty(parsedArgs);

        ...

        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process 当前运行在 system_server 进程中 */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        zygoteServer.closeServerSocket(); // 1  关闭 Zygote 进程创建的 Socket
        return handleSystemServerProcess(parsedArgs); // 2
    }

    return null;
}

system_server 进程复制了 Zygote 进程的地址空间,因此也会得到 Zygote 进程创建的 Socket,这个 Socket 对于 system_server 进程没有任何用处,因此,需要在注释 1 处关闭 Socket。 接着,在注释 2 处调用 handleSystemServerProcess 方法来启动 system_server 进程。handleSystemServerProcess 方法的代码如下所示:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    ...

    if (parsedArgs.mInvokeWith != null) {
        ...
    } else {
        ClassLoader cl = getOrCreateSystemServerClassLoader(); // 1
        if (cl != null) {
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mDisabledCompatChanges,
                parsedArgs.mRemainingArgs, cl); // 2
    }

    /* should never reach here */
}

private static ClassLoader getOrCreateSystemServerClassLoader() {
    if (sCachedSystemServerClassLoader == null) {
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
                    VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
        }
    }
    return sCachedSystemServerClassLoader;
}

在注释 1 处创建了 ClassLoader。在注释 2 处调用了 ZygoteInit.zygoteInit 方法,代码如下所示:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();

    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit(); // 1 启动 Binder 线程池
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader); // 2 进入 SystemServer.main 方法
}

在注释 1 处调用 ZygoteInit.nativeZygoteInit 方法,此处调用的是 Native 层的代码,用来启动 Binder 线程池,这样 ,system_server 进程就可以使用 Binder 与其他进程进行通信。注释 2 处是用于进入 SystemServer.main 方法。

以下是 RuntimeInit.applicationInit 方法的源代码:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, 
                                          long[] disabledCompatChanges, 
                                          String[] argv, ClassLoader classLoader) {
    ...
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

在 RuntimeInit.applicationInit 方法中主要调用了 findStaticMain 方法:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;

    try {
      	// 通过反射得到 SystemServer 类
        cl = Class.forName(className, true, classLoader); // 1
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
      	// 找到 SystemServer.main 方法
        m = cl.getMethod("main", new Class[] { String[].class }); // 2
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }

    ...
    /*
     * This throw gets caught in ZygoteInit.main(), which responds
     * by invoking the exception's run() method. This arrangement
     * clears up all the stack frames that were required in setting
     * up the process.
     */
    return new MethodAndArgsCaller(m, argv); // 3
}

static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

注释 1 处的 className 为 com.android.server.SystemServer,通过反射返回的 cl 为 SystemServer 类。在注释 2 处找到 SystemServer.main 方法。在注释 3 处将找到的 main 方法传入到 MethodAndArgsCaller 中。获取 MethodAndArgsCaller 对象的代码在 ZygoteInit.main 方法中:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    ...
    try {
        ...
        if (startSystemServer) {
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process.
            if (r != null) {
                r.run(); // 1
                return;
            }
        }
        ...
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }
	...
}

通过注释 1 处的代码可以知道,在 ZygoteInit.main 方法中会获取 MethodAndArgsCaller 对象,并调用 MethodAndArgsCaller.run() 方法。MethodAndArgsCaller 是 RuntimeInit 的静态内部类,实现了 Runnable 接口:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
static class MethodAndArgsCaller implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs }); // 1
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

注释 1 处的 mMethod 指的是 SystemServer.main 方法,调用了 mMethod.invoke 方法后,SystemServer.main 方法也会被动态调用。

2 解析 system_server 进程

以下是 SystemServer.main 方法:

// /frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
    new SystemServer().run();
}

在 SystemServer.main 方法中只调用了 SystemServer().run() 方法:

// /frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
    ...
    try {
        ...
        Looper.prepareMainLooper(); // 创建消息 Looper
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

        // Initialize native services. 加载了动态库 libandroid_servers.so
        System.loadLibrary("android_servers"); // 1 

        ...
        performPendingShutdown();

        // Initialize the system context. 创建系统的 Context
        createSystemContext();

        ...

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext); // 2
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        mDumper.addDumpable(mSystemServiceManager);

        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        ...
    } finally {
        t.traceEnd();  // InitBeforeStartServices
    }

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

    // Start services.
    try {
        t.traceBegin("StartServices");
        startBootstrapServices(t); // 3 启动引导服务
        startCoreServices(t); // 4 启动核心服务
        startOtherServices(t); // 5 启动其他服务
        startApexServices(t);
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        t.traceEnd(); // StartServices
    }

    ...

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

在注释 1 加载了动态库 libandroid_servers.so。在注释 2 处创建 SystemServiceManager,它会对系统服务进行创建、启动和生命周期管理。在注释 3 处的 startBootstrapServices() 方法中回用 SystemServiceManager 启动 ActivityManagerService、PowerManagerService、PackageManagerService 等服务。在注释 4 处的 startCoreServices() 方法中则启动 DropBoxManagerService、BatteryService、UsageStateService 和 WebViewUpdateService。在注释 5 处的 startOtherServices() 方法中启动了 CameraService、AlarmManagerService、VrManagerService 等服务。

从注释 3 、4、5 处可以 看出, 官方把系统服务分为三种类型,分别是引导服务、核心服务和其他服务,其中,其他服务是一些非要紧的和不需要立即启动的服务。 系统服务总共 100 多个,以下是其中的部分服务:

部分系统服及其作用

这些系统服务启动逻辑是相似的,这里以 ActivityTaskManagerService 举例说明:

// /frameworks/base/services/java/com/android/server/SystemServer.java
private SystemServiceManager mSystemServiceManager;
private ActivityManagerService mActivityManagerService;

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
  	...
    t.traceBegin("StartActivityManager");
    // TODO: Might need to move after migration to WM.
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService(); // 1
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm); 
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();
    t.traceEnd();
  	...
}

注释 1 处调用 SystemServiceManager.startService 方法启动了 ActivityTaskManagerService,SystemServiceManager.startService 方法如下所示:

// /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public SystemService startService(String className) {
    final Class<SystemService> serviceClass = loadClassFromLoader(className,
            this.getClass().getClassLoader());
    return startService(serviceClass); // 1
}

public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();
        Slog.i(TAG, "Starting " + name);
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

        // 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 (InstantiationException ex) {
            ...
        }
      	...

        startService(service); // 2
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

private List<SystemService> mServices;

public void startService(@NonNull final SystemService service) {
    // Check if already started
    String className = service.getClass().getName();
    if (mServiceClassnames.contains(className)) {
        Slog.i(TAG, "Not starting an already started service " + className);
        return;
    }
    mServiceClassnames.add(className);

    // Register it. 注册 Service
    mServices.add(service); // 3

    // Start it.
    long time = SystemClock.elapsedRealtime();
    try {
        service.onStart(); // 4 启动 Service
    } catch (RuntimeException ex) {
        ...
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}

注释 2 处将 ActivityTaskManagerService 添加到 mServices 中,其中 mServices 是一个存储 SystemService 类型的 ArrayList,这样就完成了 ActivityTaskManagerService 的注册工作。在注释 4 处调用 ActivityTaskManagerService.onStart() 方法就完成启动 ActivityTaskManagerService。

除了用 SystemServiceManager.startService 方法来启动系统服务外,也可以通过如下形式来启动系统服务,以 PackageManagerService 为例:

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
  	...
    IPackageManager iPackageManager;
    t.traceBegin("StartPackageManagerService");
    try {
        Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
        Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
                mSystemContext, installer, domainVerificationService,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); // 1
        mPackageManagerService = pmsPair.first;
        iPackageManager = pmsPair.second;
    } finally {
        Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
    }
  	...
}

注释 1 处直接调用 PackageManagerService.main 方法:

// /frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static Pair<PackageManagerService, IPackageManager> main(Context context,
        Installer installer, @NonNull DomainVerificationService domainVerificationService,
        boolean factoryTest, boolean onlyCore) {
    // Self-check for initial settings. 自检初始的设置
    PackageManagerServiceCompilerMapping.checkProperties();
    ...

    PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
            PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
            Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL); // 1
    t.traceEnd(); // "create package manager"

    ...

    m.installAllowlistedSystemPackages();
    IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
    ServiceManager.addService("package", iPackageManager); // 2
    final PackageManagerNative pmn = new PackageManagerNative(m);
    ServiceManager.addService("package_native", pmn);
    LocalManagerRegistry.addManager(PackageManagerLocal.class, 
                                    m.new PackageManagerLocalImpl());
    return Pair.create(m, iPackageManager);
}

在注释 1 出直接创建 PackageManagerService 然后将 PackageManagerService 注册到 ServiceManager 中。

ServiceManager 用来管理各种 Service,使用 C/S 架构,Binder 通信机制。Client 端要使用某个 Service,先要到 ServiceManager 查询 Service 的相关信息,然后根据 Service 的相关信息与 Server 端建立通信通路。

出现哪些情况会导致 Zygote 进程重启?

进程间通信
出现以下四种情况会导致 Zygote 进程重启:

  • (onresart) Zygote 进程被杀;
  • (oneshot = false) system_server 进程被杀死;
  • ServiceManager 进程被杀死,这是因为 ServiceManager 先启动,然后 Zygote 进程后启动,最后是 system_server 进程启动,启动的顺序决定了依赖性。system_server 中的 Service 都需要和 ServiceManager 进行通讯,因此,当 ServiceManager 进程被杀死的时候,system_server 将杀死自身,从而导致 Zygote 进程被杀死;
  • (onresart) SurfaceFlinger 进程被杀死;

SurfaceFlinger 是整个 Android系统渲染的核心进程,所有的应用的渲染逻辑都会在 SurfaceFlinger 中进行处理,最终会把处理后的图像数据交给 CPU 或者 GPU 进行绘制。SurfaceFlinger 还负责处理窗口管理、动画效果和硬件加速等功能,确保流畅的用户界面体验。

SurfaceFlinger 几乎贯穿了整个 Android 领域,从 HAL 硬件抽象层到 Framework 层,从 CPU 绘制到 OpenGL 等硬件绘制。

GPU(Graphic Processing Unit)图形处理器/图形处理单元,是一种专门设计用于处理计算机图形和图像的处理器。它可以加速计算机图形渲染和处理操作,提高计算机图形和图像的性能和质量。

system_server 为什么要在 Zygote 进程中启动,而不是 init 进程直接启动呢?

Zygote 作为一个孵化器,可以提前加载一些资源,这样 fork 时,基于 Copy-On-Write 机制创建的其他进程就能直接使用这些资源,而不用重新加载。比如 system_server 就可以直接使用 Zygote 进程中的 JNI 函数、共享库、常用类以及主题资源。

为什么要使用 Zygote 进程去孵化应用进程,而不是用 system_server 去孵化呢?

首先 system_server 相比于 Zygote 进程多运行了 ATMS、AMS、WMS 等服务,这些对一个应用程序来说是不需要的。另外进程的 fork 对多线程不友好,仅会将发起调用的线程拷贝到子进程,这可能会导致死锁,而 system_server 中肯定是有很多线程的。

是怎么导致死锁的?

每个锁都有一个所有者,即最后一次 lock 它的线程。假设,在父进程 fork 之前,有一个线程 lock 了某个对象,fork 之后,在子进程中,锁被复制了,但是所有的额外线程都没有被复制,因此,在子线程来看来,这个锁是没有持有者的,因此也无法对它进行解锁,这时就发生了死锁。

另外,如果在后续的某个时刻,即使父进程释放了这把锁,子进程是感知不到的,因此,子进程仍然持有锁。

Zygote 为什么不采用 Binder 机制进行 IPC 通信?

Binder 机制中存在 Binder 线程池,是多线程的的。如果 Zygote 采用 Binder 的话就存在 fork 和多线程的问题了。其实严格来说,Binder 机制不一定要多线程,所谓的 Binder 线程只不过是在循环读取 Binder 驱动的消息而已,只注册一个 Binder 线程也是可以工作的,比如 ServiceManager 就是这样工作的。实际上 Zygote 尽管没有采取 Binder 机制,它也不是单线程的,但是在 fork 前主动停止了其他线程,fork 后又重新启动了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值