The whole vold mechanism should be the system layer, and the interaction with the framwork layer is mentioned in android--4.2 Vold Mount Management _commandlistener (ii), which is communicated through a "vold" socket, Here is an analysis of the framework in charge of communicating with Vold:mountservice
Writing is not easy, reproduced please specify the source: http://blog.csdn.net/jscese/article/details/38978387
One. Mountservice Start:
In the/frameworks/base/services/java/com/android/server/systemserver.java, there are:
if (! " 0 ". Equals (Systemproperties.get (" System_init.startmountservice "))) { try { / * * * Notificationmanagerservice is dependant in Mountservice, * (for MEDIA/USB notifications) so we must start Mountservi CE first. * /SLOG.I (TAG, "Mount Service"); Mountservice = new Mountservice (context); Servicemanager.addservice ("Mount", Mountservice); } catch (Throwable e) { reportwtf ("Starting Mount Service", e); } }
One of the system services to start the boot, for more information about the initial system startup: android--Start-up process analysis
Public Mountservice (Context context) {Mcontext = context; Synchronized (Mvolumeslock) {readstoragelistlocked ();//Resolution/frameworks/base/core/res/res/xml/storage_list.xml Save volume to Mountservice list:mvolumes}//Xxx:this'll go away soon in favor of Imountserviceobserver MPms = (packagemanagerservice) servicemanager.getservice ("package"); Mhandlerthread = new Handlerthread ("Mountservice"); Mhandlerthread.start (); Mhandler = new Mountservicehandler (Mhandlerthread.getlooper ());//New Message Processing handler//Watch for user changes fin Al Intentfilter userfilter = new Intentfilter (); Userfilter.addaction (intent.action_user_added); Userfilter.addaction (intent.action_user_removed); Mcontext.registerreceiver (muserreceiver, userfilter, NULL, mhandler);//Registered broadcast receive//Watch for USB changes on Primary V Olume Final Storagevolume primary = Getprimaryphysicalvolume (); if (primary! = NULL && Primary.allowmassstorage ()) {Mcontext.registerreceiver (musbreceiver, New Intentfil ter (usbmanager.action_usb_state), NULL, Mhandler); }//Add OBB Action Handler to Mountservice thread. Mobbactionhandler = new Obbactionhandler (Mhandlerthread.getlooper ()); /* * Create the connection to vold with a maximum queue of twice the * amount of containers we ' d ever expe CT to has. This keeps a * "ASEC list" from blocking a thread repeatedly. */mconnector = new Nativedaemonconnector (This, "Vold", Max_containers * 2, Vold_tag, 25);//Create a Vold listener to receive Syste The socket message for VOLD in M is thread thread = new Thread (mconnector, Vold_tag); Thread.Start ();//start thread, Nativedaemonconnector implement Runnable interface, implement in Run//ADD ourself to the Watchdog monitors if enable D. if (watchdog_enable) {watchdog.getinstance (). Addmonitor (this); } }
Two. Mountservice Receive socket:
Above see constructs the nativedaemonconnector used to receive the socket message from the lower layer, first look at the structure:
Nativedaemonconnector (inativedaemonconnectorcallbacks Callbacks, string socket, int responsequeuesize, string LogTag, int maxlogsize) { mcallbacks = callbacks;//callback msocket = socket;//socket name Mresponsequeue = new Resp Onsequeue (responsequeuesize);//Build a response queue Msequencenumber = new Atomicinteger (0); TAG = LogTag! = null? LogTag: "Nativedaemonconnector"; Mlocallog = new Locallog (maxlogsize); }
Open the run method on the monitor thread above:
public void Run () { Handlerthread thread = new Handlerthread (TAG +). CallbackHandler "); TAG is Voldconnector, here a new message processing thread named Voldconnector.callbackhandler is used for processing Thread.Start () after receiving the vold socket below. Mcallbackhandler = new Handler (Thread.getlooper (), this); Create handler to distribute the message while (true) { try { listentosocket ();//While loop to listen for socket } catch (Exception e) {
loge ("Error in Nativedaemonconnector:" + e); Systemclock.sleep ();}}}
Look inside.
Listentosocket:
private void Listentosocket () throws IOException {localsocket socket = null; try {socket = new localsocket (); Create local socket localsocketaddress address = new Localsocketaddress (Msocket, localsocketaddress . namespace.reserved);//Get the address of the server vold socket socket.connect;//connect InputStream InputStream = Soc Ket.getinputstream (); Synchronized (mdaemonlock) {moutputstream = Socket.getoutputstream (); }//get Input output stream mcallbacks.ondaemonconnected ();//Callback, execute in Mountservice, initialize some volume state information byte[] buffer = new Byte[buffer_size]; int start = 0; while (true) {int count = inputstream.read (buffer, start, buffer_size-start);//Read data to Buffer if (Count < 0) {//disconnect, jump out of the current while, the external while loop re-calls the function connection Loge ("got" + Count + "reading with start = "+ start); Break } Add Our starting point to the count and reset the start. Count + = start; start = 0; for (int i = 0; i < count; i++) {if (buffer[i] = = 0) {Final String rawevent = new String (buffer, start, I-start, charsets.utf_8); Log ("RCV <-{" + Rawevent + "}"); Try {final Nativedaemonevent event = nativedaemonevent.parserawevent ( Rawevent); Parse into event Save if (event.isclassunsolicited ()) {//Determine event's code range code >= && C Ode <//todo:migrate to sending Nativedaemonevent instances Mcallbackhandler.sendmessage (Mcallbackhandler.obtainmessage (//Send message to handle to distribute the event Event.getcode (), Event.getrawevent ())); } else {Mresponsequeue.add (Event.getcmdnumber (), event);//Join to Response queue }} catch (IllegalArgumentException e) {log ("Problem parsing message : "+ rawevent +"-"+ e); } start = i + 1; } } ... } }}
The handle processing in Nativedaemonconnector is:
@Override Public Boolean handlemessage (Message msg) { String event = (string) msg.obj; try { if (!mcallbacks.onevent (Msg.what, event, Nativedaemonevent.unescapeargs (event))) {//callback to Mountservice The Oneent function log (String.Format ("Unhandled event '%s '", event)); } } catch (Exception e) { Loge ("Error Handling "+ Event +" ': "+ e); } return true; }
To Mountservice in onEvent:
public boolean onEvent (int code, String Raw, string[] cooked) {if (debug_events) {StringBuilder bu Ilder = new StringBuilder (); Builder.append ("OnEvent::"); Builder.append ("raw=" + raw); if (cooked! = null) {builder.append ("cooked ="); for (String str:cooked) {builder.append ("" + str); }} slog.i (TAG, builder.tostring ()); } if (code = = Voldresponsecode.volumestatechange) {////////* * One of the volume according to Vold code execution * * S we ' re managing have changed state. * Format: "NNN Volume <label> <path> state changed * from <old_#> (<old_str>) to <n Ew_#> (<new_str>) "*/Notifyvolumestatechange (cooked[2], cooked[3], in Teger.parseint (Cooked[7]), Integer.parseint (cooked[10]); Update Status} ElSe if ((code = = voldresponsecode.volumediskinserted) | | (Code = = voldresponsecode.volumediskremoved) | | (Code = = Voldresponsecode.volumebadremoval)) if (code = = voldresponsecode.volumediskinserted) {//If you receive a message that inserts disk, the mount operation is performed new thre AD () {@Override public void run () {try { int RC; if (rc = domountvolume (path)) = storageresultcode.operationsucceeded) {SLOG.W (TAG, Strin G.format ("Insertion mount failed (%d)", RC)); }} catch (Exception ex) {SLOG.W (TAG, "Failed to mount Media on Inserti On ", ex); }}}.start (); } ...}
You can see that the corresponding operation is performed according to the code value, Directvolume in Directvolume in android--4.2 vold Mount Management _directvolume/volume (v) :: responsecode::volumediskinserted was sent in the handleblockevent.
Mountservice in the vold socket is generally the case!
Three. Mountservice issued command:
From the above Domountvolume to parse, Mountservice in the volume of the various operations are required to be converted into a socket command in accordance with the Vold, so vold in order to correctly parse the recognition call!
private int Domountvolume (String path) { int rc = storageresultcode.operationsucceeded; Final Storagevolume volume; Synchronized (Mvolumeslock) { volume = mvolumesbypath.get (path); } if (debug_events) slog.i (TAG, "domountvolume:mouting" + path); try { Mconnector.execute ("volume", "Mount", path);//Call to execute in Nativedaemonconnector } ...}
In Nativedaemonconnector:
Public nativedaemonevent Execute (String cmd, Object ... args) throws nativedaemonconnectorexception { final Nativedaemonevent[] events = executeforlist (cmd, args);//Sent by Executeforlist, returns the Nativedaemoneent event if ( Events.length! = 1) { throw new nativedaemonconnectorexception ( "expected exactly one response, but received" + E vents.length); } return events[0]; }
Final call to:
Public nativedaemonevent[] Execute (int timeout, String cmd, Object ... args) throws Nativedaemonconnectorexc Eption {final Arraylist<nativedaemonevent> events = Lists.newarraylist (); Final int sequencenumber = Msequencenumber.incrementandget (); Final StringBuilder cmdbuilder = new StringBuilder (integer.tostring (SequenceNumber)). Append ("); Final Long startTime = Systemclock.elapsedrealtime (); Makecommand (cmdbuilder, cmd, args); The conversion is made into a standard command final String logcmd = cmdbuilder.tostring (); /* includes cmdnum, cmd, args */log ("SND, {" + Logcmd + "}"); Cmdbuilder.append (' n '); Final String sentcmd = cmdbuilder.tostring (); /* logcmd + */synchronized (Mdaemonlock) {if (Moutputstream = = null) {throw new Nat Ivedaemonconnectorexception ("Missing output stream"); } else {try {moutputstream.write (sentcmd.getBytes (Charsets.utf_8)); Write the converted Sentcmd} catch (IOException e) {throw new Nativedaemo by the output stream obtained in Listentosocket Nconnectorexception ("Problem sending command", e); } } } ...}
The process of Mountservice down command is basically like this!
Simple flowchart:
At this point, the framework and Vold analysis is here!
android--4.2 Vold Mount Management _mountservice (vi)