Android起動のSystemServer起動
18077 ワード
SystemServerはAndroidシステムの核心であり、APKアプリケーションで直接対話できるシステムサービスの大部分はこのプロセスで実行されている.よく見られるのはWindowManagerServer(Wms)、Activity ManagerSystemService(AmS)、PackageManagerServer(PmS)などである.
トランザクションは、1つのスレッドでSystemServerプロセスに存在します.
startSystemServer
SystemServerはzygoteで起動したときにforkが起動したので、まずZygoteInitに戻ります.JAvaクラスでSystemServerの起動を見てみましょう.zygote起動中、startSystemServerを呼び出してsystemServerを起動します.
このクラスはExceptionから継承され,Runnableが実現された.この異常はZygoteInit.JAvaクラスのmain関数catchを実行しrun()関数を実行し、反射によりSystemServerのmain関数を起動します.
次はZygoteInitです.JAvaクラスのmain関数は、例外のコードを取得します.
システムサーバを起動しましたJAvaのmain関数です.ソースコードは(baseservicesjavacomandroidserver).
SystemServer.java
このクラスのコードの一部を見てみましょう.
システムアプリケーションフレームワーク層のXxxServiceManagerの準備完了
トランザクションは、1つのスレッドでSystemServerプロセスに存在します.
startSystemServer
SystemServerはzygoteで起動したときにforkが起動したので、まずZygoteInitに戻ります.JAvaクラスでSystemServerの起動を見てみましょう.zygote起動中、startSystemServerを呼び出してsystemServerを起動します.
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,3006,3007",
"--capabilities=130104352,130104352",
"--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);
}
return true;
}
まずZygoteを通過する.forkSystemServer forkはサブプロセスを出し、uid、gidなどの新しいプロセスの情報を設定するためにいくつかのパラメータを入力します.関数が戻った後、サブプロセスpid=0の場合、handleSystemServer 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.
Libcore.os.umask(S_IRWXG | S_IRWXO);
//ps system 261 98 391508 49008 ffffffff 4005c880 S system_server, system_server parsedArgs.niceName
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
null, parsedArgs.remainingArgs);
} else {
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}
/* should never reach here */
}
この関数では、親プロセスzygoteからコピーされたsocketサービスを閉じるためにcloseServerSocket()を最初に呼び出します.zygoteがsocketリクエストの処理を傍受すれば十分です.そして実行を続けますzygoteInit()はJNIでapp_を呼び出しますmain.cppのonZygoteInitは、スレッドプールを起動してBinderイベントを処理します.最後にinvokeStaticMain()関数により異常MethodAndArgsCallerを放出した.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;
}
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);
}
}
}
このクラスはExceptionから継承され,Runnableが実現された.この異常はZygoteInit.JAvaクラスのmain関数catchを実行しrun()関数を実行し、反射によりSystemServerのmain関数を起動します.
次はZygoteInitです.JAvaクラスのmain関数は、例外のコードを取得します.
} catch (MethodAndArgsCaller caller) {
caller.run();
}
システムサーバを起動しましたJAvaのmain関数です.ソースコードは(baseservicesjavacomandroidserver).
SystemServer.java
このクラスのコードの一部を見てみましょう.
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
public static void main(String[] args) {
// SamplingProfiler
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
// 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.
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!
dalvik.system.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);
// libandroid_servers.so
System.loadLibrary("android_servers");
//init1() native , JNI system_init.cpp system_init() , Dalvik 。 , Java init2() , Java init2() .
init1(args);
}
// init2() 。
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
// ServerThread , , , ServerThread run() 。
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
main()関数はまずinit 1()関数を実行し、init 1()関数はnative関数であり、JNIを介してsystem_を最終的に呼び出すinit.cppのsystem_Init()関数:extern "C" status_t system_init()
{
ALOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p
", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// SurfaceFlinger
SurfaceFlinger::instantiate();
}
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// sensor service
SensorService::instantiate();
}
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
ALOGI("System server: starting Android runtime.
");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
ALOGI("System server: starting Android services.
");
JNIEnv* env = runtime->getJNIEnv();
if (env == NULL) {
return UNKNOWN_ERROR;
}
// “com/android/server/SystemServer” SystemServer.java
jclass clazz = env->FindClass("com/android/server/SystemServer");
if (clazz == NULL) {
return UNKNOWN_ERROR;
}
// SystemServer.java init2
jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
if (methodId == NULL) {
return UNKNOWN_ERROR;
}
// init2()
env->CallStaticVoidMethod(clazz, methodId);
ALOGI("System server: entering thread pool.
");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
ALOGI("System server: exiting thread pool.
");
return NO_ERROR;
}
system_Init()関数コールバックinit 2()関数、init 2()関数はサーバThreadスレッドを起動して各種サービスとその他のいくつかの初期化作業を追加し、サーバThreadは内部クラスであり、大体コードは以下の通りである.class ServerThread extends Thread {
...
@Override
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
Looper.prepareMainLooper();
...
String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);
final boolean headless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
// , , , : 、 、Wifi、 ,USB
...
Context context = null;
...
// Create a shared handler thread for UI within the system server.
// This thread is used by at least the following components:
// - WindowManagerPolicy
// - KeyguardViewManager
// - DisplayManagerService
HandlerThread uiHandlerThread = new HandlerThread("UI");
uiHandlerThread.start();
Handler uiHandler = new Handler(uiHandlerThread.getLooper());
uiHandler.post(new Runnable() {
@Override
public void run() {
//Looper.myLooper().setMessageLogging(new LogPrinter(
// Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode logging for UI Looper");
}
}
});
// Create a handler thread just for the window manager to enjoy.
HandlerThread wmHandlerThread = new HandlerThread("WindowManager");
wmHandlerThread.start();
Handler wmHandler = new Handler(wmHandlerThread.getLooper());
wmHandler.post(new Runnable() {
@Override
public void run() {
//Looper.myLooper().setMessageLogging(new LogPrinter(
// android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
android.os.Process.setCanSelfBackground(false);
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode logging for WM Looper");
}
}
});
// Critical services...
boolean onlyCore = false;
try {
// Wait for installd to finished starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
Slog.i(TAG, "Waiting for installd to be ready.");
installer = new Installer();
installer.ping();
// EntropyService, ,
Slog.i(TAG, "Entropy Mixer");
ServiceManager.addService("entropy", new EntropyMixer());// Context.getSystemService (String name)
// ServiceManager
Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
// ActivityManagerService, context
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
// uiHandler、wmHandler
Slog.i(TAG, "Display Manager");
display = new DisplayManagerService(context, wmHandler, uiHandler);
ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
...
// wmHandler
Slog.i(TAG, "Input Manager");
inputManager = new InputManagerService(context, wmHandler);
// uiHandler、wmHandler
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power, display, inputManager,
uiHandler, wmHandler,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
ActivityManagerService.setSystemProcess();
...
Slog.i(TAG, "System Content Providers");
ActivityManagerService.installSystemProviders();
...
// 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(), display);
...
Slog.i(TAG, "Init Watchdog");
Watchdog.getInstance().init(context, battery, power, alarm,
ActivityManagerService.self());
...
ActivityManagerService.self().setWindowManager(wm);
...
// wmHandler
if (context.getResources().getBoolean(
com.android.internal.R.bool.config_dreamsSupported)) {
try {
Slog.i(TAG, "Dreams Service");
// Dreams (interactive idle-time views, a/k/a screen savers)
dreamy = new DreamManagerService(context, wmHandler);
ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);
} catch (Throwable e) {
reportWtf("starting DreamManagerService", e);
}
}
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
}
...
try {
Slog.i(TAG, "NetworkPolicy Service");
networkPolicy = new NetworkPolicyManagerService(
context, ActivityManagerService.self(), power,
networkStats, networkManagement);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
} catch (Throwable e) {
reportWtf("starting NetworkPolicy Service", e);
}
...
}
...
if (safeMode) {
ActivityManagerService.self().showSafeModeOverlay();
}
...
// ,
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
if (!headless) startSystemUi(contextF);
try {
if (mountServiceF != null) mountServiceF.systemReady();
} catch (Throwable e) {
reportWtf("making Mount Service ready", e);
}
...
try {
if (telephonyRegistryF != null) telephonyRegistryF.systemReady();
} catch (Throwable e) {
reportWtf("making TelephonyRegistry ready", e);
}
}
});
// 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!");
}
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}
}
システムアプリケーションフレームワーク層のXxxServiceManagerの準備完了