Today found some guy wrote a post about System Server and I want to discuss more about this topic.
Here are the steps:
1. kernel boot and start init and init will run the command in init.rc.
We can find:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
zygote will be started as a server and it will start Systemserver.
2. in frameworks/base/core/java/com/android/internal/os/ZygoteInit.java, after preloadClasses and preloadResources, it will check the arguments and start system server directly from Zygote If requested
startSystemServer();
this will fork a pid for Systemserver and start SystemServer
3. after this, we can look into frameworks/base/services/java/com/android/server/SystemServer.java
591 public class SystemServer
592 {
593 private static final String TAG = "SystemServer";
594
595 public static final int FACTORY_TEST_OFF = 0;
596 public static final int FACTORY_TEST_LOW_LEVEL = 1;
597 public static final int FACTORY_TEST_HIGH_LEVEL = 2;
598
599 static Timer timer;
600 static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
601
602 // The earliest supported time. We pick one day into 1970, to
603 // give any timezone code room without going into negative time.
604 private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
605
606 /**
607 * This method is called from Zygote to initialize the system. This will cause the native
608 * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
609 * up into init2() to start the Android services.
610 */
611 native public static void init1(String[] args);
612
613 public static void main(String[] args) {
614 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
615 // If a device's clock is before 1970 (before 0), a lot of
616 // APIs crash dealing with negative numbers, notably
617 // java.io.File#setLastModified, so instead we fake it and
618 // hope that time from cell towers or NTP fixes it
619 // shortly.
620 Slog.w(TAG, "System clock is before 1970; setting to 1970.");
621 SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
622 }
623
624 if (SamplingProfilerIntegration.isEnabled()) {
625 SamplingProfilerIntegration.start();
626 timer = new Timer();
627 timer.schedule(new TimerTask() {
628 @Override
629 public void run() {
630 SamplingProfilerIntegration.writeSnapshot("system_server");
631 }
632 }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
633 }
634
635 // The system server has to run all of the time, so it needs to be
636 // as efficient as possible with its memory usage.
637 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
638
639 System.loadLibrary("android_servers");
640 init1(args);
641 }
642
643 public static final void init2() {
644 Slog.i(TAG, "Entered the Android system server!");
645 Thread thr = new ServerThread();
646 thr.setName("android.server.ServerThread");
647 thr.start();
648 }
649 }
The first thing that happens is that the server will load a native library called android_servers that provides interfaces to native functionality. Source files for this lib are placed in frameworks/base/services/jni/. Then the native init method that will setup native services is called, init1(args), and executed:
In com_android_server_SystemServer.cpp
26 static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
27 {
28 system_init();
29 }
30
31 /*
32 * JNI registration.
33 */
34 static JNINativeMethod gMethods[] = {
35 /* name, signature, funcPtr */
36 { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
37 };
38
39 int register_android_server_SystemServer(JNIEnv* env)
40 {
41 return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
42 gMethods, NELEM(gMethods));
43 }
The name of the function that implements this is system_init() and the it resides in frameworks/base/cmds/system_server/library/system_init.cpp:
54 extern "C" status_t system_init()
55 {
56 LOGI("Entered system_init()");
57
58 sp<ProcessState> proc(ProcessState::self());
59
60 sp<IServiceManager> sm = defaultServiceManager();
61 LOGI("ServiceManager: %p/n", sm.get());
62
63 sp<GrimReaper> grim = new GrimReaper();
64 sm->asBinder()->linkToDeath(grim, grim.get(), 0);
65
66 char propBuf[PROPERTY_VALUE_MAX];
67 property_get("system_init.startsurfaceflinger", propBuf, "1");
68 if (strcmp(propBuf, "1") == 0) {
69 // Start the SurfaceFlinger
70 SurfaceFlinger::instantiate();
71 }
72
73 // Start the sensor service
74 SensorService::instantiate();
75
76 // On the simulator, audioflinger et al don't get started the
77 // same way as on the device, and we need to start them here
78 if (!proc->supportsProcesses()) {
79
80 // Start the AudioFlinger
81 AudioFlinger::instantiate();
82
83 // Start the media playback service
84 MediaPlayerService::instantiate();
85
86 // Start the camera service
87 CameraService::instantiate();
88
89 // Start the audio policy service
90 AudioPolicyService::instantiate();
91 }
92
93 // And now start the Android runtime. We have to do this bit
94 // of nastiness because the Android runtime initialization requires
95 // some of the core system services to already be started.
96 // All other servers should just start the Android runtime at
97 // the beginning of their processes's main(), before calling
98 // the init function.
99 LOGI("System server: starting Android runtime./n");
100
101 AndroidRuntime* runtime = AndroidRuntime::getRuntime();
102
103 LOGI("System server: starting Android services./n");
104 runtime->callStatic("com/android/server/SystemServer", "init2");
105
106 // If running in our own process, just go into the thread
107 // pool. Otherwise, call the initialization finished
108 // func to let this process continue its initilization.
109 if (proc->supportsProcesses()) {
110 LOGI("System server: entering thread pool./n");
111 ProcessState::self()->startThreadPool();
112 IPCThreadState::self()->joinThreadPool();
113 LOGI("System server: exiting thread pool./n");
114 }
115 return NO_ERROR;
116 }
117
After setting up the native services there is a callback at line 104:
runtime->callStatic("com/android/server/SystemServer", "init2");
to init2() above to create the server thread. This thread will start the remaining services in the system according to the necessary start order. A snippet of the initial sequence gives:
In frameworks/base/services/java/com/android/server/SystemServer.java:
134 try {
135 Slog.i(TAG, "Entropy Service");
136 ServiceManager.addService("entropy", new EntropyService());
137
138 Slog.i(TAG, "Power Manager");
139 power = new PowerManagerService();
140 ServiceManager.addService(Context.POWER_SERVICE, power);
141
142 Slog.i(TAG, "Activity Manager");
143 context = ActivityManagerService.main(factoryTest);
144
145 Slog.i(TAG, "Telephony Registry");
146 ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
147
148 AttributeCache.init(context);
149
150 Slog.i(TAG, "Package Manager");
151 pm = PackageManagerService.main(context,
152 factoryTest != SystemServer.FACTORY_TEST_OFF);
We see that the power manager is started first, followed by the activity manager and the other services. There are a lot more services started after these initial and if you are interested take look in the SystemServer.java file. Each service is running in a separate Dalvik thread in the SystemServer process.