本来一直在分析WIFI service,后来一直往底层追溯,就跟踪到了Android的service manager等“大户”的启动,再往上追就到了init了。先大概记录一下启动的流程,以后有空了再补充某些步骤的细节。由于分析的是Kernel起来之后剩下的启动过程,所以从init进程开始:
一,init
Init是由kernel启动的用户级进程,它始终是第一个存在进程。init起来之后会解析init.rc和init.{hardware}.rc,然后根据其内容启动基本服务和做些其他的东西。init*rc里面可以有(Actions, Commands, Services, Options)四种类型的声明,另外再分析。下面先看看init.rc里面的两行:
service servicemanager /system/bin/servicemanager
...
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
...
二,ServiceMangaer与app_process
其中servicemanager的代码为frameworks/base/cmds/servicemanager/service_manager.c,ServiceManager总管所有service(frameworks层次的service)的注册与查找(详情点击这里),先运行它主要是为后面的app_process启动zygote的过程提供前提条件。
app_prceoss的代码为frameworks/base/cmds/app_process/app_main.cpp,其主函数如下:
int main(int argc, const char* const argv[])
{
...
AppRuntime runtime;
...
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
...
}
} else {
...
}
}
其中以"com.android.internal.os.ZygoteInit"为类名调用AppRuntime : public AndroidRuntime的start()函数来启动zygote,其代码在frameworks/base/core/jni/AndroidRuntime.cpp中,start函数如下:
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
...
if (startVm(&mJavaVM, &env) != 0)
goto bail;
...
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
...
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
startVm启动dalvik虚拟机,startReg负责把注册一些jni函数,然后就是找到名字为ZygoteInit的类并运行其main()函数。
三,ZygoteInit类
下面看看这个类的main函数,代码在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,主函数如下:
public static void main(String argv[]) {
try {
...
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
...
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
因为在AndroidRuntime::start中,"true"参数由strArray带进来,所以会调用到 startSystemServer()函数:
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* 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,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
...
/* Request to fork the system server process */
pid = Zygote.forkSystemServer( // 具体实现查看dalvik/vm/InternalNative.c
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
设置一堆启动参数之后,调用forkSystemServer启动子进程来跑handleSystemServerProcess(),父进程返回继续忙其他的事情(就是runForkMode或者runSelectLoopMode),然后这个函数又绕到了RuntimeInit.zygoteInit(parsedArgs.remainingArgs):
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
...
commonInit(); // 做些初始化的工作
zygoteInitNative();
...
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
invokeStaticMain这个函数在根据startArgs找到类名为"com.android.server.SystemServer"的main函数(还检查了public和static属性),然后通过throw new ZygoteInit.MethodAndArgsCaller(m, argv)返回。注意观察中间这些函数都带throws ZygoteInit.MethodAndArgsCaller的,所以这个 ZygoteInit.MethodAndArgsCaller最后会被ZygoteInit的main函数catch到然后通过 caller.run();启动SystemServer的main函数。
四,SystemServer类
类的代码在frameworks/base/services/java/com/android/server/SystemServer.java中,主函数:
public static void main(String[] args) {
...
System.loadLibrary("android_servers");
init1(args);
}
先显式加载libandroid_servers,这个库由frameworks/base/services/jni中的代码生成,加载时会把onload.cpp里的JNI_OnLoad()跑一遍把jni函数注册上去:
register_android_server_PowerManagerService(env);
register_android_server_InputManager(env);
register_android_server_LightsService(env);
register_android_server_AlarmManagerService(env);
register_android_server_BatteryService(env);
register_android_server_UsbService(env);
register_android_server_VibratorService(env);
register_android_server_SystemServer(env);
register_android_server_location_GpsLocationProvider(env);
库加载完后,SystemServer的main函数再调用init1(args)进行下一步的工作,这个函数在SystemServer.java中是这样定义的native public static void init1(String[] args);所以是通过jni的方式进行调用,init1的实现在libandroid_servers库的代码中:
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
}
system_init()的实现在frameworks/base/cmds/system_server/library/system_init.cpp中(生成的是libsystem_server):
extern "C" status_t system_init()
{
... // 先启动SurfaceFinger和SensorService等关键服务
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
// Start the sensor service
SensorService::instantiate();
// 如果是emulator的话直接在这里把下面的service也拉起来
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::instantiate();
// Start the media playback service
MediaPlayerService::instantiate();
// Start the camera service
CameraService::instantiate();
// Start the audio policy service
AudioPolicyService::instantiate();
}
...
LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");
...
return NO_ERROR;
}
通过callStatic调用,又绕回了java层去,SystemServer.java中得init2如下:
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
ServerThread的start()调用run()来启动所有的JAVA Service:
@Override
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
Looper.prepare();
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setCanSelfBackground(false);
// Check whether we failed to shut down last time we tried.
{
final String shutdownAction = SystemProperties.get(
ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
if (shutdownAction != null && shutdownAction.length() > 0) {
boolean reboot = (shutdownAction.charAt(0) == '1');
final String reason;
if (shutdownAction.length() > 1) {
reason = shutdownAction.substring(1, shutdownAction.length());
} else {
reason = null;
}
ShutdownThread.rebootOrShutdown(reboot, reason);
}
}
String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);
LightsService lights = null;
PowerManagerService power = null;
BatteryService battery = null;
ConnectivityService connectivity = null;
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
BluetoothService bluetooth = null;
BluetoothA2dpService bluetoothA2dp = null;
HeadsetObserver headset = null;
DockObserver dock = null;
UsbService usb = null;
UiModeManagerService uiMode = null;
RecognitionManagerService recognition = null;
ThrottleService throttle = null;
// Critical services...
try {
...
// 类似下面这段代码,先创建JAVA Service类(new或者getInstance)
// 再调用ServiceManager的addService API将系统的各种JAVA Service加进来
try {
Slog.i(TAG, "Connectivity Service");
connectivity = ConnectivityService.getInstance(context);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
// WIFI相关的service由connectivity service管理
// getInstance()会调用ConnectivityService()构造函数,其中会通过
// WifiStateTracker wst = new WifiStateTracker(context, mHandler);
// WifiService wifiService = new WifiService(context, wst);
// ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
// wifiService.startWifi(); 来启动wifi service
// wifi相关的另文分析
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Connectivity Service", e);
}
...
// It is now time to start up the app processes...
// Service加完后,可以通过systemReady()回调来通知各个Service现在可以开始自己的服务了
if (devicePolicy != null) {
devicePolicy.systemReady();
}
if (notification != null) {
notification.systemReady();
}
if (statusBar != null) {
statusBar.systemReady();
}
wm.systemReady();
power.systemReady();
try {
pm.systemReady();
} catch (RemoteException e) {
}
// These are needed to propagate to the runnable below.
final StatusBarManagerService statusBarF = statusBar;
final BatteryService batteryF = battery;
final ConnectivityService connectivityF = connectivity;
final DockObserver dockF = dock;
final UsbService usbF = usb;
final ThrottleService throttleF = throttle;
final UiModeManagerService uiModeF = uiMode;
final AppWidgetService appWidgetF = appWidget;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
final RecognitionManagerService recognitionF = recognition;
final LocationManagerService locationF = location;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
((ActivityManagerService)ActivityManagerNative.getDefault())
.systemReady(new Runnable() { // 这个回调将会通过发送intent.CATEGORY_HOME启动第一个activity,具体代码待分析
public void run() {
Slog.i(TAG, "Making services ready");
if (statusBarF != null) statusBarF.systemReady2();
if (batteryF != null) batteryF.systemReady();
if (connectivityF != null) connectivityF.systemReady();
if (dockF != null) dockF.systemReady();
if (usbF != null) usbF.systemReady();
if (uiModeF != null) uiModeF.systemReady();
if (recognitionF != null) recognitionF.systemReady();
Watchdog.getInstance().start();
// It is now okay to let the various system services start their
// third party code...
if (appWidgetF != null) appWidgetF.systemReady(safeMode);
if (wallpaperF != null) wallpaperF.systemReady();
if (immF != null) immF.systemReady();
if (locationF != null) locationF.systemReady();
if (throttleF != null) throttleF.systemReady();
}
});
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
}
五,后续
至此,提供给app运行的环境已经搭建起来,但是某些步骤还是不太完善需要以后补充。其中关system_init()这个函数也可以通过/system/bin/system_server来显式调用。找到一段说明如下:
There is another way to start system server, which is through a program named system_server whose source is frameworks/base/cmds/system_server/system_main.cpp. It also calls system_init to start system services. So there is a question: why does Android have two methods to start system services? My guess is that directly start system_server may have synchronous problem with zygote because system_server will call JNI to start SystemServer::init2, while at that time zygote may not start JAVA VM yet. So Android uses another method. After zynote is initialized, fork a new process to start system services.
大致意思是,可以通过system_server这个命令调用system_init来启动system services,但是为什么Android要使用上述的方式来启动呢。据猜测是如果直接用命令来启动的话会跟zygote有同步的问题存在,因为system_init会通过JNI来调用SystemServer::init2,如果这时候zygote尚未启动JAVA VM就会出问题了。