SystemServer分析过程
2016-03-25 14:59
387 查看
SystemServer是由zygote进程fork出来的进程.
Step 1 如下代码,启动zygote进程以后,SystemServer进程由zygote start出来
Step 2. RuntimeInit.zygoteInit 中main调用StartSystemServer方法来启动SystemServer,接下来具体分析下startSystemServer方法.
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
在startSystemServer方法中主要做了三件事情
1.设置uid 和 gid 为1000.SystemServer执行类为com.android.server.SystemServer
2.调用zygote类中forkSystemServer来fork出来子进程.(注意对于fork出来的SystemServer,Zygote进程会进行判断是否启动成功,如果启动不成功Zygote进程会自动退出,另外有一个SetSigChildHander()函数还需要处理SIGCHLD信号的函数SigChidHander,其中SigChidHander来接受子进程死亡的信号后,除了调用waitpid()来防止子进程变成僵尸进程,还需要判断子进程是否是SystemServer进程,如果是systemServer被杀死,zygote则会自杀,这样就导致Init进程杀死所有用户进程并且重启Zygote)
3.fork出SystemServer进程后,在fork出的进程中调用handleSystemServerProcess()来初始化SystemServer进程.
//这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中
这里的方法作用是
1)通过closeServerSocket();函数关闭了从zygote进程来的子进程,因为这里用不到,
2)接着将SystemServer进程umask设置为0077,这样创建的文件属性就是0700了
只有SystemServer进程可以访问
3)将进程名称参数改成''system_server'.
Step 3 接下来来分析下SystemServer核心入口main函数.
这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中
有以上代码可以知道main 函数 调用了run方法'new SystemServer().run();',
接下来我们具体分析下run方法实现的内容
1.main 函数里面首先要初始化工作,然后加载libandroid_servers.so文件.
改函数libandroid_servers.so实现库代码如下.
2.调用nativeInit()方法初始化native层Binder服务.
3.调用createSystemContext()来获取Context.
4.创建SystemServiceManager的对象mSystemServiceManager.这个对象负责系统Service启动.
5.调用 startBootstrapServices();startCoreServices(); startOtherServices();创建并且运行所有java服务.
6.调用Loop.loop进入处理消息循环.
2.启动各项服务包括AMS PMS WMS等其他服务
Step 1 如下代码,启动zygote进程以后,SystemServer进程由zygote start出来
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote stream 666 onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart media onrestart restart netd
Step 2. RuntimeInit.zygoteInit 中main调用StartSystemServer方法来启动SystemServer,接下来具体分析下startSystemServer方法.
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
public static void main(String argv[]) { try { RuntimeInit.enableDdms(); // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } registerZygoteSocket(socketName); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); // Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup gcAndFinalize(); // Disable tracing so that forked processes do not inherit stale tracing tags from // Zygote. Trace.setTracingEnabled(false); if (startSystemServer) { startSystemServer(abiList, socketName); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(abiList); closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } } private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { long capabilities = posixCapabilitiesAsBits( OsConstants.CAP_BLOCK_SUSPEND, OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_RESOURCE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG ); /* 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,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "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) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } handleSystemServerProcess(parsedArgs); } return true; }
在startSystemServer方法中主要做了三件事情
1.设置uid 和 gid 为1000.SystemServer执行类为com.android.server.SystemServer
2.调用zygote类中forkSystemServer来fork出来子进程.(注意对于fork出来的SystemServer,Zygote进程会进行判断是否启动成功,如果启动不成功Zygote进程会自动退出,另外有一个SetSigChildHander()函数还需要处理SIGCHLD信号的函数SigChidHander,其中SigChidHander来接受子进程死亡的信号后,除了调用waitpid()来防止子进程变成僵尸进程,还需要判断子进程是否是SystemServer进程,如果是systemServer被杀死,zygote则会自杀,这样就导致Init进程杀死所有用户进程并且重启Zygote)
static void SigChldHander(int signal_number){ pid_t pid; while((pid = waitpid(-1, &status, WNOHANG)) > 0){ ...... if(pid == gSystemServerPid) { kill(getpid(), SIGKILL) ;//如果死亡的是SystemServer进程,Zygote将退出 } } }
3.fork出SystemServer进程后,在fork出的进程中调用handleSystemServerProcess()来初始化SystemServer进程.
//这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中
/** * Finish remaining work for the newly forked system server process. */ private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); // set umask to 0077 so new files and directories will default to owner-only permissions. Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); } if (parsedArgs.invokeWith != null) { String[] args = parsedArgs.remainingArgs; // If we have a non-null system server class path, we'll have to duplicate the // existing arguments and append the classpath to it. ART will handle the classpath // correctly when we exec a new process. if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); } WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); } else { ClassLoader cl = null; if (systemServerClasspath != null) { cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(cl); } /* * Pass the remaining arguments to SystemServer. */ RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */ }
这里的方法作用是
1)通过closeServerSocket();函数关闭了从zygote进程来的子进程,因为这里用不到,
2)接着将SystemServer进程umask设置为0077,这样创建的文件属性就是0700了
只有SystemServer进程可以访问
3)将进程名称参数改成''system_server'.
Step 3 接下来来分析下SystemServer核心入口main函数.
这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中
public static void main(String[] args) { new SystemServer().run(); }
private void run() { // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it shortly. if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // If the system has "persist.sys.language" and friends set, replace them with // "persist.sys.locale". Note that the default locale at this point is calculated // using the "-Duser.locale" command line flag. That flag is usually populated by // AndroidRuntime using the same set of system properties, but only the system_server // and system apps are allowed to set them. // // NOTE: Most changes made here will need an equivalent change to // core/jni/AndroidRuntime.cp b699 p 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", ""); } // Here we go! Slog.i(TAG, "Entered the Android system server!"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system // property so that it is in sync. We can't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Enable the sampling profiler. if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); mProfilerSnapshotTimer = new Timer(); mProfilerSnapshotTimer.schedule(new TimerTask() { @Override public void run() { SamplingProfilerIntegration.writeSnapshot("system_server", null); } }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); } // Mmmmmm... more memory! VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Some devices rely on runtime fingerprint generation, so make sure // we've defined it before booting further. Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true); // Ensure binder calls into the system always run at foreground priority. BinderInternal.disableBackgroundScheduling(true); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); // Initialize native services. System.loadLibrary("android_servers"); nativeInit(); // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Start services. try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } // For debug builds, log event loop stalls to dropbox for analysis. if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
有以上代码可以知道main 函数 调用了run方法'new SystemServer().run();',
接下来我们具体分析下run方法实现的内容
1.main 函数里面首先要初始化工作,然后加载libandroid_servers.so文件.
改函数libandroid_servers.so实现库代码如下.
2.调用nativeInit()方法初始化native层Binder服务.
3.调用createSystemContext()来获取Context.
4.创建SystemServiceManager的对象mSystemServiceManager.这个对象负责系统Service启动.
5.调用 startBootstrapServices();startCoreServices(); startOtherServices();创建并且运行所有java服务.
6.调用Loop.loop进入处理消息循环.
2.启动各项服务包括AMS PMS WMS等其他服务
相关文章推荐
- 多个TextView跑马灯效果实现
- HDU 1252 Hike on a Graph 题目读懂就能做
- jquery随便小特效之常见网站顶部导航栏
- CoordinateLayout框架初步总结(未完)
- C++实现voronoi图
- SVN 将主干的代码合并到分支上
- 2015百度产品笔试题(全)(无答案)
- 实验一 命令解释程序的编写
- FragmentTabHost的使用
- lua string库
- Android官方开发文档Training系列课程中文版:管理Activity的生命周期之停止和重启Activity
- linux驱动开发 主设备号与次设备号
- LeetCode 334 Increasing Triplet Subsequence
- 折半排序
- win10 print spooler 开启不了1068错误
- Python接收开源中国GITOSC WebHook的POST数据
- java编写文件路径用的File.separator和直接打“\\”有什么区别啊?
- 实验一、命令解释程序
- Sql Server中启用分布式事务小结
- sass安装