现在的位置: 首页 > 移动开发 > 正文

Android情景分析之深入解析system_server

2019年07月27日 移动开发 ⁄ 共 13130字 ⁄ 字号 评论关闭

system_server进程作为zygote的嫡长子,其重要性是不言而喻的。下面我们通过代码来深入分析下system_server的实现。

system_server的诞生

在深入解析zygote的时候,我们看过system_server的启动过程,这里我们再来回顾下:

/* 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,1032,3001,3002,3003,3006,3007",
    "--capabilities=" + capabilities + "," + capabilities,
    "--runtime-init",
    "--nice-name=system_server",
    "com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {
    parsedArgs = new ZygoteConnection.Arguments(args);
    ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
    ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

    /* Request to fork the system server process */
    pid = Zygote.forkSystemServer(
            parsedArgs.uid, parsedArgs.gid,
            parsedArgs.gids,
            parsedArgs.debugFlags,
            null,
            parsedArgs.permittedCapabilities,
            parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
    throw new RuntimeException(ex);
}

/* For child process */
if (pid == 0) {
    handleSystemServerProcess(parsedArgs);
}

从上面的代码中,我们可以看出system_server是zygote通过调用Zygote.forkSystemServer函数来创建的。先来看看forkSystemServer的实现:

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
	preFork();
	int pid = nativeForkSystemServer(
        	uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
	postFork();
	return pid;
}

该函数主要通过native函数nativeForkSystemServer来完成主要功能,对应文件为dalvik\vm\native\dalvik_system_Zygote.cpp:

/*
 * native public static int nativeForkSystemServer(int uid, int gid,
 *     int[] gids, int debugFlags, int[][] rlimits,
 *     long permittedCapabilities, long effectiveCapabilities);
 */
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        const u4* args, JValue* pResult)
{
    pid_t pid;
    pid = forkAndSpecializeCommon(args, true);

    /* The zygote process checks whether the child process has died or not. */
    if (pid > 0) {
        int status;
        gDvm.systemServerPid = pid;	// 赋值system_server pid
        /* There is a slight window that the system server process has crashed
         * but it went unnoticed because we haven't published its pid yet. So
         * we recheck here just to make sure that all is well.
         */
        if (waitpid(pid, &status, WNOHANG) == pid) {
            ALOGE("System server process %d has died. Restarting Zygote!", pid);

			// 如果system_server进程在fork完毕,执行的过程中挂了,那么
			// Zygote就把自己给杀了,简直就是同生共死啊。
            kill(getpid(), SIGKILL);
        }
    }
    RETURN_INT(pid);
}

最后通过forkAndSpecializeCommon函数fork出system_server进程,接着来看:

/*
 * Utility routine to fork zygote and specialize the child process.
 */
static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{
    …….
	
    if (!gDvm.zygote) {
        dvmThrowIllegalStateException(
            "VM instance not started with -Xzygote");

        return -1;
    }

    if (!dvmGcPreZygoteFork()) {
        ALOGE("pre-fork heap failed");
        dvmAbort();
    }
	
	/*
设置子进程的信号处理函数,子进程system_server如果挂了,那么,
Zygote会调用kill函数把自己给杀了。
	*/
    setSignalHandler();

    dvmDumpLoaderStats("zygote");
    pid = fork();	// fork分裂出子进程

if (pid == 0) {
// …. 根据传进来的参数设置子进程相关属性
}
….
}

OK,至此,system_server作为zygote的嫡长子,已经被创建出来了。并且,它的地位也是非常高的,和zygote同生共死。它那么重要,具体承担了什么工作呢?下面我们来继续分析。

system_server的使命

/* For child process */
if (pid == 0) {
     handleSystemServerProcess(parsedArgs);
}

Zygote fork出了system_server之后,后者便调用handleSystemServerProcess开始了自己的使命。

/**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
		
		// 关闭从zygote那里继承下来的socket
        closeServerSocket();
		
        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Libcore.os.umask(S_IRWXG | S_IRWXO);
		
		// 修改进程名为system_server
        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        if (parsedArgs.invokeWith != null) {
            ……
        } else {
            /*
             * Pass the remaining arguments to SystemServer.
             */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
        }
}

继续来看RuntimeInit.zygoteInit:

public static final void zygoteInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        redirectLogStreams();
		// 做一些常规初始化
        commonInit();

		// native层的初始化
        nativeZygoteInit();

		// 调用应用程序java层的main 方法
        applicationInit(targetSdkVersion, argv);
}

Native层的初始化 – nativeZygoteInit

对应native层函数如下:

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

这里的gCurRuntime是什么?还记得app_process(zygote)的main函数嘛?

int main(…)
{
	…
	AppRuntime runtime; // 其实就是这个
	…
}

AppRuntime是继承自AndroidRuntime的类:

static AndroidRuntime* gCurRuntime = NULL;	// AndroidRuntime类的全局变量
AndroidRuntime::AndroidRuntime() :
        mExitWithoutCleanup(false)
{
    …….
assert(gCurRuntime == NULL);
gCurRuntime = this;		// 开始赋值
}

因为system_server是zygote通过fork分裂出来的,所以system_server进程本身也拥有gCurRuntime这个对象。再回过头来看onZygoteInit的处理,AppRuntime中重写了onZygoteInit函数:

virtual void onZygoteInit()
{
……
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool(); // 启动一个线程,用于Binder通信。
}

上述内容和Binder通信相关,我们现在还不必深究。简而言之,system_server调用完nativeZygoteInit之后,便于Binder通信系统建立了联系,这样system_server就能使用Binder通信了。

进入java层– applicationInit

private static void applicationInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            return;
        }

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs);
}

VMRuntime进行简单的初始化之后,invokeStaticMain函数就开始进入system_server的java层main函数中开始执行。其中,根据前面硬编码的启动参数可知,system_server java层的类为com.android.server.SystemServer。

invokeStaticMain函数的调用很有意思,我们接着往下看:

private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

        try {
			// 加载com.android.server.SystemServer这个类
            cl = Class.forName(className);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
			// 获得main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } 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);
        }

        int modifiers = m.getModifiers();
		// 判断main函数的类型
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * 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.
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

ZygoteInit.MethodAndArgsCaller是一个继承自Exception的类,invokeStaticMain最后并没有直接调用com.android.server.SystemServer的main 方法,而是抛出了一个ZygoteInit.MethodAndArgsCalle类型的异常。

那么这个异常是在哪里被捕获的呢?上述代码的注释其实也已经解释的很清楚了,在ZygoteInit.main()中,我们回过头来看看:

    public static void main(String argv[]) {
        try {
            ……

            if (argv[1].equals("start-system-server")) {
                startSystemServer();
            } 
            ……
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            ……
        }
}

main函数中通过try-catch最终捕获到了MethodAndArgsCaller异常,并通过异常类的run函数来处理。

public static class MethodAndArgsCaller extends Exception
            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;
        }
		
		// run函数调用main函数
        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                ……
            }
        }
    }
}

至此,system_server进入java世界开始执行。

system_server的真面目

public static void main(String[] args) {
        ……
        System.loadLibrary("android_servers");
        Slog.i(TAG, "Entered the Android system server!");

        // Initialize native services.
        nativeInit();

        // This used to be its own separate thread, but now it is
        // just the loop we run on the main thread.
        ServerThread thr = new ServerThread();
        thr.initAndLoop();
}

函数首先加载了libandroid_servers.so文件,之后调用nativeInit初始化,最后initAndLoop启动各种系统服务。

Native服务初始化 - nativeInit

nativeInit是一个native函数,代码在frameworks\base\services\jni\com_android_server_SystemServer.cpp中:

static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsensorservice", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the sensor service
        SensorService::instantiate();
    }
}

这个函数主要是根据属性配置文件来确定是否需要初始化Sensor Service,这里就不多介绍了。

Java层服务初始化 – ServerThread类

启动一个ServerThread线程,其主要用来初始化Java层的各种服务,并且通过Binder接收各种服务消息。我们直接来看initAndLoop函数。这个函数比较长,大致看看它都干了些什么:

public void initAndLoop() {
		// 初始化Lopper
        Looper.prepareMainLooper();
	
		// 设置线程优先级
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);

        BinderInternal.disableBackgroundScheduling(true);
        android.os.Process.setCanSelfBackground(false);

		......

        // bootstrap services
        boolean onlyCore = false;
        boolean firstBoot = false;
        try {
            .....

            Slog.i(TAG, "Power Manager");
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);

            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);
        } catch (RuntimeException e) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting bootstrap service", e);
        }

        boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
        boolean disableMedia = SystemProperties.getBoolean("config.disable_media", false);
        boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
        boolean disableTelephony = SystemProperties.getBoolean("config.disable_telephony", false);
        boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
        boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
        boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
        boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);

        try {
            Slog.i(TAG, "Display Manager");
            display = new DisplayManagerService(context, wmHandler);
            ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);

            Slog.i(TAG, "Telephony Registry");
            telephonyRegistry = new TelephonyRegistry(context);
            ServiceManager.addService("telephony.registry", telephonyRegistry);

            Slog.i(TAG, "Scheduling Policy");
            ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());

            AttributeCache.init(context);

            if (!display.waitForDefaultDisplay()) {
                reportWtf("Timeout waiting for default display to be initialized.",
                        new Throwable());
            }

            Slog.i(TAG, "Package Manager");
            // Only run "core" apps if we're encrypting the device.
            String cryptState = SystemProperties.get("vold.decrypt");
            if (ENCRYPTING_STATE.equals(cryptState)) {
                Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
                onlyCore = true;
            } else if (ENCRYPTED_STATE.equals(cryptState)) {
                Slog.w(TAG, "Device encrypted - only parsing core apps");
                onlyCore = true;
            }

            pm = PackageManagerService.main(context, installer,
                    factoryTest != SystemServer.FACTORY_TEST_OFF,
                    onlyCore);
            try {
                firstBoot = pm.isFirstBoot();
            } catch (RemoteException e) {
            }

            ActivityManagerService.setSystemProcess();

            Slog.i(TAG, "Entropy Mixer");
            ServiceManager.addService("entropy", new EntropyMixer(context));

            Slog.i(TAG, "User Service");
            ServiceManager.addService(Context.USER_SERVICE,
                    UserManagerService.getInstance());

            mContentResolver = context.getContentResolver();

            // The AccountManager must come before the ContentService
            try {
                // TODO: seems like this should be disable-able, but req'd by ContentService
                Slog.i(TAG, "Account Manager");
                accountManager = new AccountManagerService(context);
                ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting Account Manager", e);
            }

            Slog.i(TAG, "Content Manager");
            contentService = ContentService.main(context,
                    factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

            Slog.i(TAG, "System Content Providers");
            ActivityManagerService.installSystemProviders();

            Slog.i(TAG, "Lights Service");
            lights = new LightsService(context);

            Slog.i(TAG, "Battery Service");
            battery = new BatteryService(context, lights);
            ServiceManager.addService("battery", battery);

            Slog.i(TAG, "Vibrator Service");
            vibrator = new VibratorService(context);
            ServiceManager.addService("vibrator", vibrator);

            Slog.i(TAG, "Consumer IR Service");
            consumerIr = new ConsumerIrService(context);
            ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);

            // only initialize the power service after we have started the
            // lights service, content providers and the battery service.
            power.init(context, lights, ActivityManagerService.self(), battery,
                    BatteryStatsService.getService(),
                    ActivityManagerService.self().getAppOpsService(), display);

            Slog.i(TAG, "Alarm Manager");
            alarm = new AlarmManagerService(context);
            ServiceManager.addService(Context.ALARM_SERVICE, alarm);

            Slog.i(TAG, "Init Watchdog");
            Watchdog.getInstance().init(context, battery, power, alarm,
                    ActivityManagerService.self());
            Watchdog.getInstance().addThread(wmHandler, "WindowManager thread");

            Slog.i(TAG, "Input Manager");
            inputManager = new InputManagerService(context, wmHandler);

            Slog.i(TAG, "Window Manager");
            wm = WindowManagerService.main(context, power, display, inputManager,
                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                    !firstBoot, onlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

            ActivityManagerService.self().setWindowManager(wm);

            inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
            inputManager.start();

            display.setWindowManager(wm);
            display.setInputManager(inputManager);
	}

	......

        Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
}

以上代码省略了很多,大致就是ServerThread线程启动各种系统服务,最后通过Looper.loop()来进行消息循环,然后处理消息。

system_server总结

【上篇】
【下篇】

抱歉!评论已关闭.