Android情景分析之深入解析system_server
system_server进程作为zygote的嫡长子,其重要性是不言而喻的。下面我们通过代码来深入分析下system_server的实现。system_server的诞生在深入解析zygote的时候,我们看过system_server的启动过程,这里我们再来回顾下:/* Hardcoded command line to start the system server */
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总结
更多推荐
所有评论(0)