Recent learning advanced decryption summary SystemService start-up Deepen understanding and memory

SystemService Before starting , Let's take a look first Zygote What did the process do

Zygote process

stay Android In the system ,DVM and ART, Key services of application process and running system SystemServer There is a process Zygote Process , We also call it an incubator . It passed fork To create application processes and SystemServer process , hesitate Zygote The process is created at startup DVM perhaps ART, Therefore, by fork The application process and SystemServer A process can get a DVM perhaps ART Instance copy of .Zygote Process startup does the following things :

1 establish AppRuntime And call it start method , start-up Zygote process ;
2 establish Java Virtual machine and Java Virtual machine registration JNI method ;
3 adopt JNI call ZygoteInit Of main Function entry Zygote Of Java Frame layer ;
4 adopt registerZygoteSocket Method to create a server Socket, And passed runSelectLoop Method wait AMS Come at your request 5 Create a new application process ;
6 start-up SystemServer process .

Here is the sequence diagram

one   Zygote start Java Entrance of frame floor

start-up Zygote The entrance of , In fact, it is ZygoteInit.java , Let's see how it works main Function implementation .
//com.android.internal.os.ZygoteInit.java public static void main(String
argv[]) { .... try { 1. Create a server Socket , The name is "zygote"
zygoteServer.registerServerSocket(socketName); if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis()); 2 Used to preload resources preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload } else {
Zygote.resetNicePriority(); } ... if (startSystemServer) { 3. start-up SystemServer
process startSystemServer(abiList, socketName, zygoteServer); } Log.i(TAG,
"Accepting command socket connections"); 4. wait for AMS request
zygoteServer.runSelectLoop(abiList); // Clean or close the corresponding Socket
zygoteServer.closeServerSocket(); } catch (Zygote.MethodAndArgsCaller caller) {
caller.run(); } catch (Throwable ex) { Log.e(TAG, "System zygote died with
exception", ex); zygoteServer.closeServerSocket(); throw ex; } }
ZygoteInit.main()  I did four things

 1 Create a Server intention ”zygote“ Of name Socket, For waiting AMS request Zygote To create a new application process .

 2  Preprocessing loading classes and resources .

 3   according to JNI Whether to start or not can be judged by the information transmitted SystemServer 

 4  wait for AMS request , Used to create a new application process .

 

1. zygoteServer.registerServerSocket(socketName);

look down registerServerSocket What did you do
//com.android.internal.os ZygoteServer.java void registerServerSocket(String
socketName) { if (mServerSocket == null) { int fileDesc; 1 Get it Socket name final
String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { 2. obtain Socket
The value of the environment variable String env = System.getenv(fullSocketName); 3. take Socket
The value of the environment variable is converted to the parameter of the file descriptor fileDesc = Integer.parseInt(env); } catch (RuntimeException
ex) { throw new RuntimeException(fullSocketName + " unset or invalid", ex); }
try { 4. Create file descriptor FileDescriptor fd = new FileDescriptor(); 5 Socket
The converted information is passed to the file descriptor , For specific information fd.setInt$(fileDesc); 6 Create server Socket mServerSocket =
new LocalServerSocket(fd); } catch (IOException ex) { throw new
RuntimeException( "Error binding to local socket '" + fileDesc + "'", ex); } } }
registerServerSocket It's mainly done 6 One thing

 1 Get the stitched one Socket name (ANDROID_SOCKET_zygote)

 2 hold funSocketName Socket The name is converted to the value of the system environment variable

 3  take Socket The value of the system environment variable is converted to the parameter of the file descriptor

 4 establish FileDescriptor File descriptor

 5 File scrambling parameters before transfer in

 6 establish LocalServerSocket, And pass the file operator out

The last server Socket It was created successfully , Wait on this server AMS request zygote Process to create a new application process .

2. start-up SystemServer process

Looking back  ZygoteInit main Comments for functions 3
//com.android.internal.os ZygoteInit.main->startSystemServer private static
boolean startSystemServer(String abiList, String socketName, ZygoteServer
zygoteServer) throws Zygote.MethodAndArgsCaller, RuntimeException {); ... 1. start-up
SystemServer Parameters of String args[] = { "--setuid=1000", "--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server", "--runtime-args",
"com.android.server.SystemServer", // Full class name path }; ZygoteConnection.Arguments
parsedArgs = null; int pid; try { parsedArgs = new
ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); 2 Create a subprocess , that is
SystemServer 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 the current code is running in a child process
, that is SystemServer In progress */ if (pid == 0) { if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName); } // close Zygote Process created Socket
zygoteServer.closeServerSocket(); 3 handleSystemServerProcess(parsedArgs); }
return true; }
summary startSystemServer What did you do

 1 Used to create args array , This array is used to save the startup SystemServer

 2 adopt fork Function in the current thread SystemServer process .

 3 Zygote.forkSystemServer Created pid by 0 It's running to SystemServer In progress

 

3. zygoteServer.runSelectLoop(abiList);

SystemServer After the process starts successfully , meeting ZygoteInit.Main() Execution in runSelectLoop method
// com.android.internal.os ZygoteInit.main->runSelectLoop void
runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); 1. Add to get the
Socket Of fd The value of the field fds.add(mServerSocket.getFileDescriptor()); peers.add(null);
while (true) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; 2
By traversing the fds Information transferred to pooFds Array for (int i = 0; i < pollFds.length; ++i) { pollFds[i] =
new StructPollfd(); pollFds[i].fd = fds.get(i); pollFds[i].events = (short)
POLLIN; } try { Os.poll(pollFds, -1); } catch (ErrnoException ex) { throw new
RuntimeException("poll failed", ex); } for (int i = pollFds.length - 1; i >= 0;
--i) { if ((pollFds[i].revents & POLLIN) == 0) { continue; } 3 If i == 0 So I think
Server Socket Connected to the client , That is to say, with AMS The connection is established if (i == 0) { 4 ZygoteConnection newPeer =
acceptCommandPeer(abiList); // take ZygoteConnection Add to Socket In the connection list
peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else {// If not equal to 0
, So that means AMS towards Zygote A request to create an application process was sent 5 call ZygoteConnection Of runOnce
Function to create a new application process , And after the connection is successfully created, remove the connection from the Socket In the connection list peers,fd Close in list */ boolean done =
peers.get(i).runOnce(this); if (done) { peers.remove(i); fds.remove(i); } } } }
}
summary The function above

1 mServerSocket That's where we are registerZygoteSocket Function Socket, call
mServerSocket.getFileDescriptor() Function to get the Socket Of fd Field and add to the fds
In the list . Then there's an infinite loop to wait AMS request Zygote Process creates a new application process .

2 take fds Transfer of information to pollFds Array .

3 yes pollFds Information traversal , If i == 0 So I think Server Socket Connected to the client , That is to say, with AMS The connection is established , Otherwise, it means that AMS
towards Zygote A request to create an application process was sent , And after the connection is successfully created, remove the connection from the Socket In the connection list peers,fd Close in list .

two   SystemServer Process processing

 

Enter processing SystemServer It's in  ZygoteInit.main() -> startSystemServer()  Functional  
handleSystemServerProcess  in

 

that SystemServer What did you do after the successful start ?

1 start-up Binder Thread pool . This allows communication with other processes ;
2 establish SystemServiceManager. It is used to create services for the system , Start up and lifecycle management ;

3  Start various system services .BootstrapServices(AMS,PMS etc. ),CoreServices(BatteryService,WebViewUpdateService etc. ),OtherServices(CameraSevice,AudioService,WindowManagerService etc. ).
//com.android.internal.os ZygoteInit.main private static void
handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws
Zygote.MethodAndArgsCaller { ... if (parsedArgs.invokeWith != null) { ... }
else { ClassLoader cl = null; if (systemServerClasspath != null) { 1. Created
PathClassLoader cl = createPathClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion); Thread.currentThread().setContextClassLoader(cl);
} 2. Call your own zygoteInit function ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, cl); } /* should never reach here */ }
Let's see ZygoteInit.zygoteInit How to do it
// com.android.internal.os ZygoteInit public static final void zygoteInit(int
targetSdkVersion, String[] argv, ClassLoader classLoader) throws
Zygote.MethodAndArgsCaller { if (RuntimeInit.DEBUG) { Slog.d(RuntimeInit.TAG,
"RuntimeInit: Starting application from zygote"); }
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams(); RuntimeInit.commonInit(); 1. start-up Binder Thread pool
ZygoteInit.nativeZygoteInit(); 2. get into SystemServer Of main method
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); }
ZygoteInit. zygoteInit Of  

1  For startup Binder Thread pool , such SystemServer You can get through Binder Communicate with other processes

2 Reflection call SystemServer main function .

see RuntimeInit.applicationInit
//com.android.internal.os RuntimeInit.java protected static void
applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller { .... invokeStaticMain(args.startClass,
args.startArgs, classLoader); } private static void invokeStaticMain(String
className, String[] argv, ClassLoader classLoader) throws
Zygote.MethodAndArgsCaller { Class<?> cl; try { 1. adopt
className(com.android.server.SystemServer ) Reflected SystemServer class className adopt AMS
It's coming from other places , It's not the only one cl = Class.forName(className, true, classLoader); } catch
(ClassNotFoundException ex) { throw new RuntimeException( "Missing class when
invoking static main " + className, ex); } Method m; try { 2. Get it SystemServer
main function m = cl.getMethod("main", new Class[] { String[].class }); } catch
(NoSuchMethodException ex) { ... } catch (SecurityException ex) { ... } int
modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) &&
Modifier.isPublic(modifiers))) { ... } 3. take m ,argv afferent
MethodAndArgsCaller, Then throw an exception , And in ZygoteInit.main Capture exception in throw new
Zygote.MethodAndArgsCaller(m, argv); }
3 The abnormal position is in the ZygoteInit.java main Function to capture
//com.android.internal.os ZygoteInit.java public static void main(String
argv[]) { ... if (startSystemServer) { 1. start-up SystemServer process
startSystemServer(abiList, socketName, zygoteServer); } .... 2. Catch exception } catch
(Zygote.MethodAndArgsCaller caller) { 3. implement run function caller.run(); } catch
(Throwable ex) { Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket(); throw ex; } }
Now let's see 3 At   caller.run();
com.android.internal.os Zygote.java public static class MethodAndArgsCaller
extends Exception implements Runnable { public void run() { try { Here we go
SystemServer main There's a way 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); } } }
Let's look at it again SystemServer.java main() Of Main realization
//com.android.server SystemServer.java public static void main(String[] args)
{ // Call internal run function new SystemServer().run(); } //com.android.server
SystemServer.java private void run() { try { ... establish Message of main thread Looper
Looper.prepareMainLooper(); // Initialize native services. 1. Loading dynamic library
libandroid_servers .so System.loadLibrary("android_servers"); // Check whether
we failed to shut down last time we tried. // This call may not return.
performPendingShutdown(); // Initialize the system context.
createSystemContext(); 2. establish SystemServiceManager It creates system services , Start up and lifecycle management
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); //
Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get(); } finally { traceEnd(); //
InitBeforeStartServices } // Start services. try {
traceBeginAndSlog("StartServices"); 3. SystemServiceManager It's on AMS
,PowerMS,PackageMS And other services startBootstrapServices(); 4. It's on
DropBoxManagerService,BatteryService,UsageStatsService and WebViewUpdateService
startCoreServices(); 5. It's on CameraService,AlarmManagerService,VrManagerService
And other services . startOtherServices(); SystemServerInitThreadPool.shutdown(); } catch
(Throwable ex) { Slog.e("System",
"******************************************"); Slog.e("System", "************
Failure starting system services", ex); throw ex; } finally { traceEnd(); } ...
// Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop
unexpectedly exited"); }
The above code can be summarized as follows

  1 Create message Looper

  2  Loading dynamic library libandroid_servers .so

  3  establish SystemServiceManager It creates system services , Start up and lifecycle management

  4  adopt SystemServiceManager start-up AMS ,PowerMS,PackageMS And other services

  5  start-up DropBoxManagerService,BatteryService,UsageStatsService and
WebViewUpdateService And other core services , They are all superclasses SystemServer

  6  start-up CameraService,AlarmManagerService,VrManagerService And other services

 

Technology