android--4.2 Vold Mount Management _mountservice (vi)

Source: Internet
Author: User

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)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.