(M) default APN settings for SIM card boot process analysis

Source: Internet
Author: User
Tags numeric
Recently, has been studying, default APN settings
When we see from the code and the phone, the default APN display is from the CONTENT://TELEPHONY/CARRIERS/PREFERAPN data, and this is saved through the shared preference, when the first time the phone card boot, After we have preferapn.xml the file, we find that it has been written with a value, but from the Telephonyprovider.java file, we do not find any written place, then the default APN exactly how to write and set it.
Combined with log to see the card boot process for several days, finally found the location of its write, only this article records the recent results.

First of all, the SIM card boot process, we know, is from the Makedefaultphone method of the Phonefactory.java file, and in which we can see the following paragraph

for (int i = 0; i < numphones; i++) {  
        phonebase phone = null;  
        int phonetype = Telephonymanager.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);  
      
        Sproxyphones[i] = new PhoneProxy (phone);  
    }
To create the phone object, today we will analyze the default APN process with the Gsmphone object.

Public Gsmphone (context context, Commandsinterface CI, Phonenotifier notifier, int. Phoneid) {This (context  
, CI, notifier, False, Phoneid);  } public Gsmphone (context context, Commandsinterface CI, Phonenotifier notifier, Boolean unittestmode,  
      
        int Phoneid) {super ("GSM", notifier, Context, CI, Unittestmode, Phoneid);  
        if (CI instanceof simulatedradiocontrol) {Msimulatedradiocontrol = (Simulatedradiocontrol) CI;  
        } mci.setphonetype (PHONECONSTANTS.PHONE_TYPE_GSM);  
      
        MCT = new Gsmcalltracker (this);  
        MSST = new Gsmservicestatetracker (this);  
      
        Mdctracker = new Dctracker (this);  
            if (!unittestmode) {Msimphonebookintmanager = new Simphonebookinterfacemanager (this);  
        Msubinfo = new Phonesubinfo (this);  
        } mci.registerforavailable (this, event_radio_available, null); Mci.registerforoffoRnotavailable (this, event_radio_off_or_not_available, null);  
        Mci.registerforon (this, event_radio_on, null);  
        MCI.SETONUSSD (this, EVENT_USSD, null);  
        Mci.setonsuppservicenotification (this, event_ssn, null);  
        Msst.registerfornetworkattached (this, event_registered_to_network, null);  
        Mci.setonss (this, EVENT_SS, null);  
      
        SetProperties ();  
      
        Log ("GSMPhone:constructor:sub =" + Mphoneid);  
SetProperties ();
 }
Where you create a Dctracker object to see how this class is constructed

Constructor public  
    Dctracker (Phonebase p) {  
        super (p);  
        ......  
        Update ();  
        ......  
}
First, the construction method of its parent class is called first.

/**  
     * Default constructor */  
    protected dctrackerbase (Phonebase phone) {  
        super ();  
        Mphone = phone;  
        ......  
        Muicccontroller = Uicccontroller.getinstance ();  
        Muicccontroller.registerforiccchanged (this, dctconstants.event_icc_changed, null);  
        ......  
    } 
And then go back to the Dctracker constructor, and you can see that the Update method is also called, which goes into the Update method to see

public void Update () {  
        ...  
        Registerforallevents ();  
        ONUPDATEICC ();  
        ......  
    } 
Enter the ONUPDATEICC method

@Override  
    protected void Onupdateicc () {  
        ...  
        Iccrecords newiccrecords = getuiccrecords (UICCCONTROLLER.APP_FAM_3GPP);  
      
        Iccrecords r = Miccrecords.get ();  
        if (r! = newiccrecords) {  
            ...  
            if (newiccrecords  
                    !  
                    = null) {if (mphone.getsubid () >= 0) {... Miccrecords.set (newiccrecords);  
                    Newiccrecords.registerforrecordsloaded (This  
                            , dctconstants.event_records_loaded, null);  
                }  
            }  
            ......  
        }  
}
dctconstants.event_records_loaded messages are registered via Iccrecords, and when all loads are complete, a event_records_loaded message is sent, received in Dctracker, and processed

@Override public  
    void Handlemessage (Message msg) {  
        ...  
      
        Switch (msg.what) {case  
            dctconstants.event_records_loaded:  
                onrecordsloaded ();  
                break;  
        }  
    } 
private void onrecordsloaded () {  
        ...  
        Createallapnlist ();  
        SETINITIALATTACHAPN ();  
        if (MPhone.mCi.getRadioState (). IsOn ()) {  
            if (DBG) log ("Onrecordsloaded:notifying data Availability");  
            Notifyoffapnsofavailability (phone.reason_sim_loaded);  
        }  
        Setupdataonconnectableapns (phone.reason_sim_loaded);  
}
See the Createallapnlist method again

/** * Based on the SIM operator numeric, create a list for all possible * Data Connections and setup the Prefe 
     RREDAPN.  
        */private void Createallapnlist () {mallapnsettings = new arraylist<apnsetting> ();  
        Iccrecords r = Miccrecords.get (); String operator = (r! = null)?  
        R.getoperatornumeric (): "";  
            if (operator! = null) {String selection = "Numeric = '" + operator + "'";  
            String = "_id";  
            Query only enabled APN.  
            Carrier_enabled:1 means enabled APN, 0 disabled APN.  
            Selection + = "and carrier_enabled = 1";  
      
            if (DBG) log ("createallapnlist:selection=" + selection); cursor cursor = Mphone.getcontext (). Getcontentresolver (). query (Telephony.Carriers.CONTENT_URI, NULL  
      
            , selection, NULL, by-and-by); if (cursor! = NULL) {if (Cursor.getcount () > 0) {mallapnsettings = createapnlist (cursor);  
            } cursor.close ();  
      
        }} addemergencyapnsetting ();  
      
        Dedupeapnsettings ();  
            if (Mallapnsettings.isempty ()) {if (DBG) log ("Createallapnlist:no APN found for carrier:" + operator);  
            MPREFERREDAPN = null;  
            Todo:what is the right behavior?  
        Notifynodata (DataConnection.FailCause.MISSING_UNKNOWN_APN);  
            } else {mpreferredapn = GETPREFERREDAPN ();  
                if (MPREFERREDAPN! = null &&!mpreferredapn.numeric.equals (operator)) {MPREFERREDAPN = null;  
            SETPREFERREDAPN (-1);  
        } if (DBG) log ("createallapnlist:mpreferredapn=" + mpreferredapn);  
      
        } if (DBG) log ("Createallapnlist:x mallapnsettings=" + mallapnsettings); setdataprofilesasneeded();
 }
As you can see, in this approach, the APN information for all numeric fields is obtained from the Content://telephony/carriers database, mainly through the numeric field of the current SIM card (where the database information comes from, Please review the Telephonyprovider.java file) and insert all the data into the mallapnsettings, as you can see below this code, as well as the data obtained for the preferred APN, which cannot be obtained here because it was not previously set.
Continue to view the Setupdataonconnectableapns method
private void Setupdataonconnectableapns (String reason) {  
        Setupdataonconnectableapns (reason, retryfailures.always);  
}
private void Setupdataonconnectableapns (String reason, Retryfailures retryfailures) {... for (APNC  
            Ontext apncontext:mprioritysortedapncontexts) {arraylist<apnsetting> Waitingapns = null; ... if (apncontext.getstate () = = DctConstants.State.FAILED | | apncontext.getst ate () = = DctConstants.State.RETRYING) {...//retryfailures.only_on_change-c  
                    Heck if the APNS has changed int radiotech = Mphone.getservicestate (). Getrildataradiotechnology ();  
                    arraylist<apnsetting> Originalapns = Apncontext.getoriginalwaitingapns (); if (Originalapns! = null && originalapns.isempty () = = False) {Waitingapns = Buildwai  
                        Tingapns (Apncontext.getapntype (), Radiotech);  
                         if (originalapns.size ()! = waitingapns.size () | |       Originalapns.containsall (Waitingapns) = = False) {Apncontext.releasedataconnection (re  
                        Ason);  
                        } else {continue;  
                    }} else {continue;  
            }  
                ......  
            }  
                if (apncontext.isconnectable ()) {log ("setupdataonconnectableapns:isconnectable () call Trysetupdata");  
                Apncontext.setreason (reason);  
            Trysetupdata (Apncontext, Waitingapns);
 }  
        }  
}
There's a Buildwaitingapns method and a Trysetupdata method are more important, we continue to analyze this section
/** * Build A list of APNs to is used to create PDP ' s. * * @param requestedapntype * @return Waitingapns list to being used to the Create PDP * error when WA Itingapns.isempty () */private arraylist<apnsetting> Buildwaitingapns (String requestedapntype, int radio  
        Tech) {...  
        arraylist<apnsetting> apnlist = new arraylist<apnsetting> ();  
        ......  
        Iccrecords r = Miccrecords.get (); String operator = (r! = null)?  
      
        R.getoperatornumeric (): "";  
        ... boolean usepreferred = true; try {//returns the value of usepreferred to True usepreferred =! Mphone.getcontext (). Getresources (). Getboolean ( Com.android. Internal.  
        R.BOOL.CONFIG_DONTPREFERAPN);  } catch (Resources.notfoundexception e) {if (DBG) log ("Buildwaitingapns:usepreferred notfoundexception set  
            to true ");  Usepreferred = true;
        }//We know this place, like, cannot get the value, return the value of MPREFERREDAPN to null if (usepreferred) {MPREFERREDAPN =  
        GETPREFERREDAPN (); } if (DBG) {log ("buildwaitingapns:usepreferred=" + usepreferred + "Canset Preferapn= "+ mcansetpreferapn +" mpreferredapn= "+ mpreferredapn +" Operato  
        R= "+ operator +" radiotech= "+ Radiotech +" Iccrecords r= "+ R); } ... if (mallapnsettings! = null) {...//just passed CREATEALLAPNL The Ist method gets the value of the for (apnsetting apn:mallapnsettings) {if (Apn.canhandletype (requestedapntype ) {if (Servicestate.bitmaskhastech (Apn.bearerbitmask, Radiotech)) {if (  
                        DBG) log ("buildwaitingapns:adding apn=" + APN);  
                    Apnlist.add (APN);  
            } else {            if (DBG) {log ("Buildwaitingapns:bearerbitmask:" + apn.bearerbitmask + "does"  
                        + "not include Radiotech:" + Radiotech);  }}} and else if (DBG) {log ("Buildwaitingapns:couldn ' t handle  
                Requesedapntype= "+ requestedapntype);  
        }}}} else {Loge ("mallapnsettings is null!");  
        } if (DBG) log ("Buildwaitingapns:x apnlist=" + apnlist);  
return apnlist;
 }
Returns a apnlist that is taken from the mallapnsettings and is judged by whether the apnsetting contains the required apntype, and whether it meets our needs
Then look at the Trysetupdata method, which is the incoming apnlist of the Buildwaitingapns returned by the just
Private Boolean Trysetupdata (Apncontext apncontext, arraylist<apnsetting> Waitingapns) {  
        ...  
          
        Apncontext.setwaitingapns (Waitingapns);  
      
        ......  
        Boolean retvalue = SetupData (Apncontext, Radiotech);  
        Notifyoffapnsofavailability (Apncontext.getreason ());  
        ......  
}
Look at the SetupData method again

private boolean setupdata (apncontext apncontext, int radiotech) {...  
        Apnsetting apnsetting;  
      
        Dcasyncchannel DCAC = null;  
        Get directly the first apnsetting apnsetting = APNCONTEXT.GETNEXTWAITINGAPN () in the MWAITINGAPN list;  
        ... Apncontext.setdataconnectionac (DCAC);  
        Apncontext.setapnsetting (apnsetting);  
        Apncontext.setstate (DctConstants.State.CONNECTING);  
      
        Mphone.notifydataconnection (Apncontext.getreason (), Apncontext.getapntype ());  
        Message msg = Obtainmessage ();  
        Msg.what = Dctconstants.event_data_setup_complete;  
        Msg.obj = new Pair<apncontext, integer> (Apncontext, Generation); Dcac.bringup (Apncontext, Getinitialmaxretry (), profileID, Radiotech, Mautoattachoncreation.get (), MSG, G  
      
        Eneration);  
        if (DBG) log ("setupdata:initing!");  
return true; }
Creates a dataconnection and sets its parameters, sends a EVENT_DATA_SETUP_COMPLETE message after the setting is complete, receives it in its parent class Dctrackerbase.java file, and processes

@Override public  
    void Handlemessage (Message msg) {  
        switch (msg.what) {  
            ...  
            Case Dctconstants.event_data_setup_complete:  
                ondatasetupcomplete ((AsyncResult) msg.obj);  
                break;  
        }  
    } 
Processing in the Ondatasetupcomplete method of the Dctracker

/** * A SETUP (aka Bringup) has completed, possibly with an error. 
     If * There is a error this method would call {@link #onDataSetupCompleteError}. */@Override protected void Ondatasetupcomplete (AsyncResult ar) {dcfailcause cause = DCFAILC Ause.  
        UNKNOWN;  
        Boolean handleError = false;  
      
        Apncontext apncontext = Getvalidapncontext (AR, "ondatasetupcomplete");  
      
            ... if (ar.exception = = null) {Dcasyncchannel DCAC = APNCONTEXT.GETDCAC ();  
              
                ......  
                apnsetting APN = apncontext.getapnsetting (); ...//Everything is setup if (Textutils.equals (Apncontext.getapntype (), Phone  
                    Constants.apn_type_default)) {Systemproperties.set (puppet_master_radio_stress_test, "true");  
         if (mcansetpreferapn && MPREFERREDAPN = = null) {               if (DBG) log ("ondatasetupcomplete:prefered APN is null");  
                        MPREFERREDAPN = APN;  
                        if (MPREFERREDAPN! = null) {SETPREFERREDAPN (mpreferredapn.id);  
        }  
                    }  
                }  
            ......  
        }
 ......  
}

As you can see, the preferred APN is set up here for the first time, and Apnsetting is the first apnsetting of Apnlist we've acquired in BUILDWAITINGAPN.
Okay, here we go.
This article only temporarily records the current research results, if there are errors, follow-up correction

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.