(M) SIM card boot process analysis Display name load

Source: Internet
Author: User

As mentioned earlier, the SIM card start-up process starts from the Makedefaultphone method in the Phonefactory.java file, and the DisplayName of the SIM starts with this part, and then records the results of his research.

public static void Makedefaultphone (context context) {synchronized (slockproxyphones) {if (!smadedefaults) { ...//Instantiate Uicccontroller So, all other classes can just//call Getin Stance ()///Leo, this method is a more important method of booting the SIM card during boot, needing attention//Leo, get Uicccontroller object muicccontr

            Oller = Uicccontroller.make (context, scommandsinterfaces);
                for (int i = 0; i < numphones; i++) {phonebase phone = null; Leo, based on preferred Network Mode, obtains the phonetype of the SIM card to confirm the type of phone, gsmphone or cdmaltephone type int phonetype = Te
                Lephonymanager.getphonetype (Networkmodes[i]);
                            if (Phonetype = = phoneconstants.phone_type_gsm) {PHONE = new Gsmphone (context,
                Scommandsinterfaces[i], sphonenotifier, i); } else if (Phonetype = = PHONECONSTANTS.PHONE_TYPE_CDMA) {PHONE = new CDMAltephone (context, scommandsinterfaces[i], sphonenotifier, i);

                } rlog.i (Log_tag, "Creating Phone with type =" + Phonetype + "sub =" + i);
            Leo,phone Agent, note that this phoneproxy is inherited from handler sproxyphones[i] = new PhoneProxy (phone);

            }
            ......
            RLOG.I (Log_tag, "Creating subinforecordupdater");
            Ssubinforecordupdater = new Subscriptioninfoupdater (context, sproxyphones, scommandsinterfaces);
    ......
        } }
}
In this method, the main thing is to do the following several things

1. Create a Uicccontroller object using the Make method of the Uicccontroller class

2. Create a PhoneProxy proxy class object

3. New one Subscriptioninfoupdater object

From the previous analysis, we know that the Uicccontroller class make method, mainly to create the Uicccontroller object, then we have to look at the code specifically

Leo, Singleton mode, and the Make method can only be called once, otherwise throws an exception public
static Uicccontroller make (Context C, commandsinterface[] ci) {
    Synchronized (mLock) {
        if (minstance! = null) {
            throw new RuntimeException ("Msimuicccontroller.make () should Only be called once ");
        }
        Minstance = new Uicccontroller (c, CI);
        Return (Uicccontroller) minstance;
    }
}
Leo, the second parameter is the RIL collection
private Uicccontroller (Context C, Commandsinterface []ci) {
    if (DBG) log ("Creating Uicccontroller ");
    Mcontext = C;
    MCis = CI;
    for (int i = 0; i < mcis.length; i++) {
        integer index = new Integer (i);
        Mcis[i].registerforiccstatuschanged (this, event_icc_status_changed, index);
        TODO remove this once modem correctly notifies the Unsols
        if (Decrypt_state.equals (Systemproperties.get (" Vold.decrypt ")) {
            mcis[i].registerforavailable (this, event_icc_status_changed, index);
        } else {
            MCis [I].registerforon (this, event_icc_status_changed, index);
        }
        Mcis[i].registerfornotavailable (this, event_radio_unavailable, index);
        Mcis[i].registerforiccrefresh (this, Event_sim_refresh, index);
    }
}
In the construction method of Uicccontroller, we see the registerforiccstatuschanged method of invoking the Ril class, so what is the main operation of this method?

@Override public
void registerforiccstatuschanged (Handler H, int. what, Object obj) {
    registrant R = new Registrant (h, what, obj);
    Miccstatuschangedregistrants.add (R);
}
The Registrant object is created through the arguments passed in, and is added to Miccstatuschangedregistrants, and Miccstatuschangedregistrants is the Registrantlist object.

Next we look at the second action in Phonefactory's Makedefaultphone method.

Sproxyphones[i] = new PhoneProxy (phone);
The parameters passed in, from the previous analysis, we know is the Gsmphone object (still take gsmphone as an example)

Class Methods
//Leo,phone Proxy, construction method, this Phonebase object is the phone object
in phonefactory based on Preferrednetworkmode is Cdmaltephone, or gsmphone public
phoneproxy (phonebase phone) {
    mactivephone = phone;
    ......
    Leo, create a new Icccardproxy object
    micccardproxy = new Icccardproxy (Mcontext, Mcommandsinterface, Mactivephone.getphoneid ());

    ......
}
We see that in the construction method of PhoneProxy, a new Icccardproxy object is created, the parameters passed in are context objects, RIL objects, and Phoneid

Public Icccardproxy (context context, commandsinterface ci, int phoneid) {
    ...
    Mcontext = context;
    MCi = CI;
    Mphoneid = Phoneid;
    ......
    Leo, gets the Uicccontroller object, has called the Make method of the Uicccontroller object in Phonefactory, so it can get to its object
    Muicccontroller = Uicccontroller.getinstance ();
    Leo, call the Uicccontroller object method, register event_icc_changed message
    muicccontroller.registerforiccchanged (this, event_icc_ CHANGED, null);
    ......
}
In the construction method of Icccardproxy, a new Uicccontroller object is created, and then its Registerforiccchanged method is called, paying attention to its incoming parameters, The Registerforiccchanged method of re-entering Uicccontroller

Notifies when card status changes public
void registerforiccchanged (Handler H, int. what, Object obj) {
    Synchroni Zed (MLock) {
        registrant R = new Registrant (h, what, obj);
        Miccchangedregistrants.add (r);
        Notify registrant right after registering, so that it'll get the latest ICC status,
        //otherwise which may not Happ En until there is a actual change in ICC status.
        R.notifyregistrant ();
    }
}
The main thing in this method is to do two things.

1. First create a new registrant object and add it to the miccchangedregistrants

2. The Notifyregistrant method of the object was called

The first reference is just analyzed, join miccchangedregistrants

2nd, let's look at the Notifyregistant method

public void
notifyregistrant ()
{
    internalnotifyregistrant (null, NULL);
}
/*package*/void
    internalnotifyregistrant (Object result, throwable exception)
    {
        Handler h = gethandler ();

        if (h = = null) {
            clear ();
        } else {
            Message msg = Message.obtain ();

            Msg.what = what;
            
            Msg.obj = new AsyncResult (userobj, result, exception);
            
            H.sendmessage (msg);
        }
    }
Well, from these two methods, we know that it gets the handler object and sends the message to itself, remembering the arguments we just passed in the Icccardproxy constructor. So the Handlemessage method of Icccardproxy is called here, and what is the incoming message event_icc_changed, see Icccardproxy Handlemessage

public void Handlemessage (Message msg) {
    switch (msg.what) {
        ...
        Case event_icc_changed:
            if (minitialized) {
                updateiccavailability ();
            }
            break;
        ......
    }
}
private void Updateiccavailability () {    synchronized (mLock) {   & nbsp;    ...         if (miccrecords! = Newrecords | | Muiccapplication! = Newapp | | Muicccard! = Newcard) {            if (DBG) log ("ICC changed.
Reregestering. ");
            unregisteruicccardevents ();
            Muicccard = Newcard;
            muiccapplication = Newapp;
            miccrecords = newrecords;
            registeruicccardevents ();
       }         updateexternalstate ();    }} 
Called the Registeruicccardevents method

private void Registeruicccardevents () {
        if (muicccard! = null) {
            muicccard.registerforabsent (this, event_icc_ ABSENT, NULL);
        }
        if (muiccapplication! = null) {
            Muiccapplication.registerforready (this, event_app_ready, null);
            Muiccapplication.registerforlocked (this, event_icc_locked, null);
            Muiccapplication.registerfornetworklocked (this, event_network_locked, null);
        }
        if (miccrecords! = null) {
            Miccrecords.registerforimsiready (this, event_imsi_ready, null);
            Miccrecords.registerforrecordsloaded (this, event_records_loaded, null);
            Miccrecords.registerforrecordsevents (this, event_icc_record_events, null);
        }
    }
Seeing this method, combined with the previous analysis, we know that its main done

1. Call the Registerforabsent method of Uicccard, mainly when the status of the SIM card is absent

2. Call the Uiccapplication three register methods, respectively, when the SIM card status is the corresponding state to trigger

3. Call the three register methods of Simrecords, respectively, in the corresponding state

We only analyze Simrecords's registerforrecordsloaded method here, and we know that this method creates a new registrant object and deposits it in mrecordsloadedregistrants, When the simrecords load is complete, send event_records_loaded, from the previous analysis, we also know that only mrecordsloadedregistrants notifyregistrants method is called when the The Notifyregistrant method of the registrant is called.

So when is mrecordsloadedregistrants called its notifyregistrants?

To view the onallrecordsloaded method of the Simrecords.java file, from the time the SPN name is parsed, you know that the simrecords is called after the load is finished, and the code for the Onallrecordsloaded method is as follows:

protected void onallrecordsloaded () {
    ...

    Mrecordsloadedregistrants.notifyregistrants (
        new AsyncResult (null, NULL, NULL));
}
So this will call Icccardproxy's handlemessage, and what is event_records_loaded

public void Handlemessage (Message msg) {switch (msg.what) {... case event_records_loaded:
            Update the MCC/MNC.
                if (miccrecords! = null) {String operator = Miccrecords.getoperatornumeric ();

                Log ("operator=" + operator + "mphoneid=" + Mphoneid);
                    if (operator! = null) {log ("update icc_operator_numeric=" + operator);
                    Mtelephonymanager.setsimoperatornumericforphone (Mphoneid, operator);
                    String CountryCode = operator.substring (0,3);
                                if (CountryCode! = null) {Mtelephonymanager.setsimcountryisoforphone (Mphoneid,
                    MCCTABLE.COUNTRYCODEFORMCC (Integer.parseint (CountryCode)));
                    } else {Loge ("event_records_loaded country code is null"); }} else {Loge ("event_records_loaded Operator name is null ");
                }} if (Muicccard! = null &&!muicccard.arecarrierpriviligerulesloaded ()) {
            Muicccard.registerforcarrierprivilegerulesloaded (this, event_carrier_priviliges_loaded, null);
            } else {onrecordsloaded ();
        } break;
......
    } }
When the condition is met, its onrecordsloaded method is called

private void onrecordsloaded () {
    broadcastinternaliccstatechangedintent (icccardconstants.intent_value_icc_ LOADED, NULL);
}
private void Broadcastinternaliccstatechangedintent (string value, String reason) {synchronized (mLo CK) {if (Mphoneid = = null) {Loge ("Broadcastinternaliccstatechangedintent:card Index is not set;
            return!! ");
        Return
        } Intent Intent = new Intent (action_internal_sim_state_changed); Intent.addflags (intent.flag_receiver_replace_pending |
        Intent.flag_receiver_registered_only_before_boot);
        Intent.putextra (Phoneconstants.phone_name_key, "PHONE");
        Intent.putextra (icccardconstants.intent_key_icc_state, value);
        Intent.putextra (Icccardconstants.intent_key_locked_reason, REASON);  Intent.putextra (Phoneconstants.phone_key, Mphoneid);
        SubId May is not valid.
        Log ("Sending intent action_internal_sim_state_changed" + "for Mphoneid:" + Mphoneid);
    Activitymanagernative.broadcaststickyintent (Intent, NULL, userhandle.user_all); }
}
Send action_internal_sim_state_changed Broadcast

We remember that in phonefactory there is a new, Subscriptioninfoupdater object that is registered in its construction method with a broadcast

Public Subscriptioninfoupdater (context context, phone[] PhoneProxy, commandsinterface[] ci) {
    ...
    Intentfilter intentfilter = new Intentfilter (telephonyintents.action_sim_state_changed);
    Intentfilter.addaction (icccardproxy.action_internal_sim_state_changed);
    Mcontext.registerreceiver (Sreceiver, intentfilter);
    ......
}
So when the Subscriptioninfoupdater object receives the broadcast, it processes
Private final Broadcastreceiver sreceiver = new  broadcastreceiver () {
    @Override public
    void OnReceive ( Context context, Intent Intent) {
        ...
        SendMessage (Obtainmessage (event_sim_loaded, SlotID,-1));
        ......
    }
};
public void Handlemessage (Message msg) {switch (msg.what) {... case Event_sim_loa
            Ded:handlesimloaded (MSG.ARG1);
       Break
......
    } }
private void handlesimloaded (int slotid) {
        ...

        if (Subscriptionmanager.isvalidsubscriptionid (subId)) {
            ...
            if (subinfo! = null && subinfo.getnamesource ()
                    ! = subscriptionmanager.name_source_user_input) {
                if (! Textutils.isempty (Simcarriername)) {
                    nametoset = simcarriername;
                } else {
                    nametoset = "CARD" + Integer.tostring (SlotID + 1);
                }
                Name.put (Subscriptionmanager.display_name, nametoset);
                LOGD ("Sim name =" + NameToSet);
                Contentresolver.update (Subscriptionmanager.content_uri, name,
                        Subscriptionmanager.unique_key_subscription_ ID
                        + "=" + long.tostring (subId), null);
            }

            ......
    }
At this point, the DisplayName loading of the SIM card is complete






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.