In our previous blog post we analyzed the zygote process, and we know that the zygote process has created an important process –system_server the process into an infinite loop, and then the important tasks in the Android system are given to System_ The server process, as Zygote's entropy eldest son process, system_server the significance of the process, today we analyze the system_server process.
Create System_server Process
In the main method in Zygoteinit, the System_server process is opened by calling the Startsystemserver method. The method mainly prepares some parameters for creating the System_server process and calls the local method Forksystemserver to create the system_server process. Let's take a look at the code for the Startsystemserver method:
Private Static Boolean Startsystemserver()throwsMethodandargscaller, RuntimeException {String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007","--capabilities=130104352,130104352","--runtime-init","--nice-name=system_server","Com.android.server.SystemServer", }; Zygoteconnection.arguments Parsedargs =NULL;intpidTry{Parsedargs =NewZygoteconnection.arguments (args); Zygoteconnection.applydebuggersystemproperty (Parsedargs); Zygoteconnection.applyinvokewithsystemproperty (Parsedargs);/ * Create system_server process * /PID = Zygote.forksystemserver (Parsedargs.uid, Parsedargs.gid, Parsedargs.gids, Parsedargs.debugflags,NULL, Parsedargs.permittedcapabilities, parsedargs.effectivecapabilities); }Catch(IllegalArgumentException ex) {Throw NewRuntimeException (ex); }/ * Execute in child process * / if(PID = =0) {handlesystemserverprocess (Parsedargs); }return true; }
The code here is not complicated and you can see that he called the Forksystemserver method to create a new process, and then executes the Handlesystemserverprocess method in the subprocess, the system_server process. Let's take a look at the Forksystemserver method, which is a native method corresponding to the source file in Dalvik\vm\native\dalvik_system_zygote.cpp. The code is as follows:
Static voidDalvik_dalvik_system_zygote_forksystemserver (Constu4* args, jvalue* pResult) {pid_t pid; PID = Forkandspecializecommon (args,true);/ * Zygote Process checks if its child process is dead / if(PID >0) {intStatus Alogi ("System server process%d has been created", PID); Gdvm.systemserverpid = pid;/ * If the system_server process exits, the zygote process will also be killed * / if(Waitpid (PID, &status, wnohang) = = pid) {Aloge ("System server process%d has died. Restarting zygote! ", PID); Kill (Getpid (), SIGKILL); }} return_int (PID);}
As you can see from the code, in the Forkandspecializecommon method, we create the subprocess and return the child process ID, and then I check if the system_server process exits, and if so, the zygote process will be killed, This shows its importance. Next we look at Forkandspecializecommon code, the creation of this system_server process really is thousand peaks hundred turn ah ...
Staticpid_t Forkandspecializecommon (Constu4* args,BOOLIssystemserver) {pid_t pid; uid_t uid = (uid_t) args[0]; gid_t gid = (gid_t) args[1]; arrayobject* Gids = (Arrayobject *) args[2]; U4 DebugFlags = args[3]; Arrayobject *rlimits = (Arrayobject *) args[4]; U4 Mountmode = Mount_external_none; int64_t permittedcapabilities, effectivecapabilities;Char*seinfo =NULL;Char*nicename =NULL;//Incoming parameter issystemserver to True if(Issystemserver) {permittedcapabilities = args[5] | (int64_t) args[6] << +; Effectivecapabilities = args[7] | (int64_t) args[8] << +; }Else{ ...... }if(!GDVM. Zygote) {Dvmthrowillegalstateexception ("VM instance not started With-xzygote");return-1; }//Before calling the fork function for the first time, you need to call if(!dvmgcprezygotefork ()) {Aloge ("Pre-fork Heap Failed"); Dvmabort (); } setsignalhandler ();//write some data to the log fileDvmdumploaderstats ("Zygote");//Sub-process is fork outPID = fork ();if(PID = =0) {//Here Some processing is done on the child process based on the parameters passed in, such as setting the process name, setting various IDs, etc....... }returnPID;}
At this point the System_server process is finally created, and we can see that the system_server process is also cloned by splitting the fork mechanism peculiar to the Linux system. Before fork, we have an important method of not analyzing the –setsignalhandler method, which is used to set the signal processing, let me look at the following.
Static voidSetsignalhandler () {intErrstructSigaction sa; memset (&sa,0,sizeof(SA)); Sa. Sa_handler= Sigchldhandler; Err = Sigaction (SIGCHLD, &sa,NULL);//Set signal processing function, the signal is the death of the child process signal if(Err <0) {ALOGW ("Error setting SIGCHLD handler:%s", Strerror (errno)); }}Static voidSigchldhandler (ints) {pid_t pid;intStatus while(PID = Waitpid (-1, &status, Wnohang)) >0) {/ * Print out the death status of the process we care about. * /....../* * If the process you just destroyed is system_server and kills the zygote process * This system_server process and zygote process will be restarted by the INIT process */ if(PID = = GDVM. Systemserverpid) {ALOG (Log_info, Zygote_log_tag,"Exit zygote because System server (%d) has terminated", (int) (PID); Kill (Getpid (), SIGKILL); } }if(PID <0) {ALOG (Log_warn, Zygote_log_tag,"Zygote SIGCHLD Error in Waitpid:%s", Strerror (errno)); }}
Here we find that we have already seen in the Forksystemserver method that the System_server process has been checked for death, why do we have to check again? This is to prevent the system_server process from dying when we have not yet obtained the PID of the fork process.
To summarize: the creation of the system_server process has gone through a long journey: first the native method is called in Startsystemserver forksystemserver The Forkandspecializecommon method is then called in the native method Forksystemserver The Setsignalhandler is also called before fork in the Forkandspecializecommon method to set the signal processing item. In this way, our system_server process was finally created, and he maintained a die relationship with the zygote process.
Responsibilities of the System_server process
In the startsystemserver approach we can see that after the process is created, the Handlesystemserverprocess method is executed in the child process, the system_server process, which is where System_server's responsibilities , let's look at the following:
private static void Handlesystemserverprocess (zygoteconnection.arguments parsedargs) Throws Zygoteinit.methodandargscaller {closeserversocket (); //set permissions. Libcore.os.umask (S_irwxg | S_IRWXO); ...... if (Parsedargs.invokewith! = null ) { ...... } else {/* The remaining parameters are passed to systemserver. */ Runtimeinit.zygoteinit (parsedargs.ta Rgetsdkversion, Parsedargs.remainingargs); } }
Can see the last system_server process came to the runtimeinit, its implementation in Frameworks\base\core\java\com\android\internal\os\runtimeinit.java
Public Static Final void Zygoteinit(intTargetsdkversion, string[] argv)throwsZygoteinit.methodandargscaller {if(DEBUG) SLOG.D (TAG,"runtimeinit:starting application from Zygote");//Close System.out and System.err, use Android logRedirectlogstreams ();//Do some regular initializationCommoninit ();//native layer initialization, after calling this method System_server will establish a connection with the binder communication system so that binder can be usedNativezygoteinit (); Applicationinit (Targetsdkversion, argv); }Private Static void Applicationinit(intTargetsdkversion, string[] argv)throwsZygoteinit.methodandargscaller {...Try{args =NewArguments (argv); }Catch(IllegalArgumentException ex) {SLOG.E (TAG, Ex.getmessage ());/Let the process exit return; } invokestaticmain (Args.startclass, Args.startargs); }
As you can see, we finally call the Invokestaticmain method, which is set in the Startsystemserver method, and the class name of the passed-in parameter is "Com.android.server.SystemServer"
Private Static void Invokestaticmain(String className, string[] argv)throwsZygoteinit.methodandargscaller {class<?> cl;Try{cl = Class.forName (ClassName); }Catch(ClassNotFoundException ex) {Throw NewRuntimeException ("Missing class when invoking static main"+ ClassName, ex); } Method m;Try{m = Cl.getmethod ("Main",NewClass[] {string[].class}); }Catch(Nosuchmethodexception ex) {Throw NewRuntimeException ("Missing static main on"+ ClassName, ex); }Catch(SecurityException ex) {Throw NewRuntimeException ("problem getting static main on"+ ClassName, ex); }intmodifiers = M.getmodifiers ();if(! (Modifier.isstatic (modifiers) && modifier.ispublic (modifiers))) {Throw NewRuntimeException ("Main method is not public and static on"+ ClassName); }/* The exception thrown is intercepted in Zygoteinit.main () */ Throw NewZygoteinit.methodandargscaller (M, argv); }
Let's take a look at the intercepted statement:
caller) { caller.run();//调用了caller的run方法
Run Method Code:
PublicvoidRun () {Try{Mmethod.invoke (NULL,New Object[] {Margs}); }Catch(Illegalaccessexception ex) {Throw NewRuntimeException (ex); }Catch(InvocationTargetException ex) {Throwable cause = Ex.getcause ();if(CauseinstanceofRuntimeException) {Throw(runtimeexception) cause; }Else if(Causeinstanceof Error) {Throw(Error) cause; }Throw NewRuntimeException (ex); } }
As you can see, at the end of the function throws an exception, is intercepted in Zygoteinit.main (), because the passed parameter class name is "Com.android.server.SystemServer", In this way we call the Methodandargscaller.run () method to execute the static Main method of the Systemserver class. (For Zygoteinit, refer to the previous blog post: Android source analysis –zygote Process Analysis)
Public Static void Main(string[] args) { ......//Mmmmmm ... more memory!Dalvik.system.VMRuntime.getRuntime (). Cleargrowthlimit ();//System server is running, so he needs to use the memory as efficiently as possibleVmruntime.getruntime (). Settargetheaputilization (0.8f); Environment.setuserrequired (true); System.loadlibrary ("Android_servers"); SLOG.I (TAG,"entered the Android system server!");///native method to initialize some sensor servicesNativeinit ();//Create a separate thread where the system's services are startedServerthread thr =NewServerthread (); Thr.initandloop (); }
Finally, System_server opens a new thread and executes its Initandloop method, It is also defined in the Systemserver.java, the code of the method is more, its main work is to open the system of various services, such as battery services, Bluetooth services and so on. and called the Looper Preparemainlooper method for the message loop, and then processing the message, here no longer repeat.
Finally, let's summarize:
- First, System_server executes the Handlesystemserverprocess method to accomplish its mission;
- Then call the Runtimeinit.zygoteinit method, where we have done some regular initialization work has been native layer initialization, so as to establish a connection with binder communication;
- Then call the Invokestaticmain method, and use the method of throwing the exception to intercept and execute the main method of Systemserver in Zygoteinit's Main method;
- In the main method of Systemserver, I called the Nativeinit method to initialize some sensor services and opened a separate thread to open the various services in the Android system. and calls the Looper Preparemainlooper method for the message loop, and then processes the message
Android source code Analysis--system_server Process Analysis