Links to related articles:

1. Android FrameWork – Learning Launcher

2. Android FrameWork – Start the Zygote process upon startup

3. Android FrameWork – Start the SystemServer process

Related source files:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/core/java/android/os/ServiceManager.java
/frameworks/base/core/java/android/os/ServiceManagerNative.java
/frameworks/base/core/java/com/android/internal/os/BinderInternal.java
Copy the code

The startSystemServer method is used to start the Zygote process:

private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ... String args[] = {"--setuid=1000", "--setgid=1000", "-- setgroups = 1001100 2100 3100 4100 5100 6100 7100 8100 9101 0101 8102 1103 2300 1300 2300 3300 6300 7", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { ... // create 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); } // pid == 0 Namely system_server process the if (pid = = 0) {/ / perform initialization process of system_server handleSystemServerProcess (parsedArgs); } return true; }Copy the code

1. Start the SystemServer

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { VM_HOOKS.preFork(); int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); // Enable tracing as soon as we enter the system_server. if (pid == 0) { Trace.setTracingEnabled(true); } VM_HOOKS.postForkCommon(); return pid; } // Call the native method to create the nativeForkSystemServer() method registered in androidRuntime.cpp, Call com_android_internal_os_Zygote_nativeForkSystemServer() native Private in com_android_internal_OS_ZYgote. CPP static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities); static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities, Jlong effectiveCapabilities) {pid_t PID = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,NULL, NULL); If (pid > 0) {// wait for SystemServer to exit, If (waitpid(pid, &status, WNOHANG) == PID) {RuntimeAbort(env); } } return pid; } static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jstring instructionSet, Jstring dataDir) {SetSigChldHandler(); Pid_t pid = fork(); If (pid == 0) {// Enter the child process... // gZygoteClass = com/android/internal/os/Zygote // gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks", "(ILjava/lang/String;) V"); / / equivalent to invoke the Zygote. CallPostForkChildHooks env () - > CallStaticVoidMethod (gZygoteClass gCallPostForkChildHooks, debug_flags,is_system_server ? NULL : instructionSet); . } else if (pid > 0) { // the parent process } return pid; } private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { ... if (parsedArgs.invokeWith ! = null) { ... } else { ClassLoader cl = null; if (systemServerClasspath ! = null) {/ / create the class loader, and given the current thread cl = new PathClassLoader (systemServerClasspath, this getSystemClassLoader ()); Thread.currentThread().setContextClassLoader(cl); } // RuntimeInit.zygoteInit RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } } public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { ... // Common some initializers commonInit(); // This is a native method, which is mainly to open binder driver and start binder thread, which will be explained later when analyzing binder driver. nativeZygoteInit(); // Apply initialization applicationInit(targetSdkVersion, argv, classLoader); } private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { ... final Arguments args; Arguments args = new Arguments(argv); } catch (IllegalArgumentException ex) { return; }... invokeStaticMain(args.startClass, args.startArgs, classLoader); } private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<? > cl = Class.forName(className, true, classLoader); . Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { ... } catch (SecurityException ex) { ... }... Zygoteinit.main () // try{} catch (MethodAndArgsCaller caller) {caller.run(); } throw new ZygoteInit.MethodAndArgsCaller(m, argv); }Copy the code

After a long loop, we find that we are back in the zygoteinit.main () method by throwing an exception. catch(){ MethodAndArgsCaller.run() }

2. Create SystemServer

public static class MethodAndArgsCaller extends Exception implements Runnable { ... Public void run() {try {// Main () mmethod.invoke (null, new Object[] {mArgs}); } catch (IllegalAccessException ex) { ... } } public final class SystemServer { ... public static void main(String[] args) { new SystemServer().run(); } private void run() {prepareMainLooper looper. PrepareMainLooper (); // Initialize the system context createSystemContext(); MSystemServiceManager = new SystemServiceManager(mSystemContext); // Add mSystemServiceManager to the local service member sLocalServiceObjects, SLocalServiceObjects inside is a static map collections LocalServices. The addService (SystemServiceManager. Class, mSystemServiceManager); // Start various system services try {// start boot service startBootstrapServices(); // Start the core service startCoreServices(); // startOtherServices startOtherServices(); } catch (Throwable ex) { Slog.e("System", "************ Failure starting system services", ex); throw ex; } // always execute looper.loop (); throw new RuntimeException("Main thread loop unexpectedly exited"); } private void createSystemContext() {// Create system process context information, In the process starts again, rounding ActivityThread ActivityThread = ActivityThread. SystemMain (); mSystemContext = activityThread.getSystemContext(); . } private void startBootstrapServices() {// Block waiting to establish socket channel with installd mSystemServiceManager.startService(Installer.class); // Start the service ActivityManagerService mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); / / start the service PackageManagerService mPackageManagerService = PackageManagerService. Main (mSystemContext, installer. mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mPackageManager = mSystemContext.getPackageManager(); / / set the AMS, give your ServiceManager. To manage the addService mActivityManagerService. SetSystemProcess (); . } private void startCoreServices() { ... } private void startOtherServices () {/ / start the alarm service mSystemServiceManager startService (AlarmManagerService. Class); // initialize Watchdog final Watchdog Watchdog = watchdog.getinstance (); watchdog.init(context, mActivityManagerService); InputManager = new InputManagerService(context); // WindowManagerService wm = WindowManagerService.main(...) ; / / and WindowManagerService have all given InputManagerService ServiceManager management ServiceManager. The addService (Context) WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); // Start input inputManager.start(); . / / show the start interface ActivityManagerNative getDefault () showBootMessage (...). ; StatusBar = new StatusBarManagerService(context, wm); // JobSchedulerService mSystemServiceManager.startService(JobSchedulerService.class); . // Ready WMS, PMS, AMS service wm.systemReady(); mPackageManagerService.systemReady(); mActivityManagerService.systemReady(); }... }Copy the code

There are about 80 system services in Android, all created by the SystemServer process. As an app developer, there are four things you need to be familiar with: ActivityManagerService, WindowManagerService, PackageManagerService, and InputManagerService are known as AMS, WMS, PMS, and IMS.

3. Management SystemServer

The ServiceManager manages all system services after they are started. Whether mSystemServiceManager. StartService or ServiceManager. The addService are walking ServiceManager. The addService () method:

public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } private static IServiceManager getIServiceManager() { if (sServiceManager ! = null) { return sServiceManager; } sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; } public abstract class ServiceManagerNative extends Binder implements IServiceManager { static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } IServiceManager in =(IServiceManager)obj.queryLocalInterface(descriptor); if (in ! = null) { return in; Return new ServiceManagerProxy(obj); } } class ServiceManagerProxy implements IServiceManager { private IBinder mRemote; public ServiceManagerProxy(IBinder remote) { mRemote = remote; }... // IPC driver public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1:0); Transact (ADD_SERVICE_TRANSACTION, data, reply, 0); // mRemote is the IBinder object mremote.transact (ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }}Copy the code

Finally, let’s summarize: The SystemServer process is created by the Fork of the Zygote process. After the SystemServer process is created, it creates boot services, core services, and other services, and sends the created services to the ServiceManager process for management through cross-process communication. As for how to enable ServiceManager and Binder drivers to communicate across processes, we will discuss the Binder driver in detail in a later article. Binder drivers are also the most difficult part of the FrameWork source code analysis, so hopefully we will be prepared.

Video address: pan.baidu.com/s/1j_wgzITc…

Video password: JJ4B