The Android 2.3 dial up process is analyzed from a source perspective

  • 2020-05-07 20:28:19
  • OfStack

In general, if we want to use the SIM card dial-up function, we need to do a simple configuration in the Settings, steps are :
Setup - "wireless and network -" mobile network - "(enabled data/data roaming/access point name/using 2G network/network operator only)
We must select the "enabled data" option, and then configure the access point name to access the Internet, of course, some Settings have been set according to your SIM card type default access point, at this point you can only select the "enabled data" item to complete the Internet function Settings.
What exactly do these setup steps do? We now from the point of view of the source code analysis.

1. First of all, we find the "set" mobile network UI. -- -- -- -- -- -- -- Settings java (/ packages/apps/Phone src/com android/phone/Settings java)
Settings.java:
The code for the "data enabled" option is as follows:
 
...... 
else if (preference == mButtonDataEnabled) { 
if (DBG) log("onPreferenceTreeClick: preference == mButtonDataEnabled."); 
ConnectivityManager cm = 
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); 
cm.setMobileDataEnabled(mButtonDataEnabled.isChecked()); 
return true; 
} 
...... 

In the code, we get an ConnectivityManager object and call the setMobileDataEnable(boolean b) method of that object. We set it according to the parameters passed in. Let's look at 1 ConnectivityManager class.

2. ConnectivityManager.java(/frameworks/base/core/java/android/net/ConnectivityManager.java)
At this point, the data has entered the frameworks layer.
The setMobileDataEnable() method code is as follows:
 
IConnectivityManager mService; 
...... 
 public ConnectivityManager(IConnectivityManager service) { 
        if (service == null) { 
            throw new IllegalArgumentException( 
                "ConnectivityManager() cannot be constructed with null service"); 
        } 
        mService = service; 
    } 
...... 
public void setMobileDataEnabled(boolean enabled) { 
try { 
mService.setMobileDataEnabled(enabled); 
} catch (RemoteException e) { 
} 
} 

Here we want to know what IConnectivityManager class, is based on IConnectivityManager aidl interface automatically generated a java class, and we have our own 1 Service inherited the inner classes: Stub, in our own to implement this Service is ConnectivityService dial-up Internet access, so according to AIDL just, as we know, in the code mService is ConnectivityService class of objects, so the code is actually call here the object ConnectivityService setMobileDataEnable () method.

3. ConnectivityService.java(/frameworks/./base/services/java/com/android/server/ConnectivityService.java)
The setMobileDataEnable() method code is as follows:
 
public void setMobileDataEnabled(boolean enabled) { 
enforceChangePermission(); 
if (DBG) Slog.d(TAG, "setMobileDataEnabled(" + enabled + ")"); 
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA, 
(enabled ? ENABLED : DISABLED), 0)); 
} 

Here is a message sent out, mHandler received the message:
 
case EVENT_SET_MOBILE_DATA: 
{ 
boolean enabled = (msg.arg1 == ENABLED); 
handleSetMobileData(enabled); 
break; 
} 

Upon receipt of the message, the handleSetMobileData() method is called:
 
private NetworkStateTracker mNetTrackers[]; 
...... 
private void handleSetMobileData(boolean enabled) { 
        ...... 
if (enabled) { 
if (mNetTrackers[ConnectivityManager.TYPE_MOBILE] != null) { 
if (DBG) { 
Slog.d(TAG, "starting up " + mNetTrackers[ConnectivityManager.TYPE_MOBILE]); 
} 
mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect(); 
} 
            ...... 
} 
 } 

If the "enabled data" option has been selected, the parameter "enabled" passed in at this time should be "true", so the if statement block in the code will be processed, that is, execute:
 
mNetTrackers[ConnectivityManager.TYPE_MOBILE].reconnect(); 

In ConnectivityManager, TYPE_MOBILE is 0, so this is a call
 
mNetTracker[0].reconnect() 

However, NetworkStateTracker is an abstract class, so the details are left to its subclass MobileDataStateTracker.java.

4. MobileDataStateTracker.java(/frameworks/base/core/java/android/net/MobileDataStateTracker.java)
This class contains multiple data connections, including MMS, SUPL,DUN, etc.,
The call flow in es95.java looks like this:
 
<PRE class=java name="code">mPhoneService = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));</PRE>......<BR> 
reconnect->mPhoneService.enableApnType(apnType);<P></P> 
<PRE></PRE> 
mPhoneService It's the client of the telephone service, it's server The end is actually PhoneInterfaceManager object  
<P></P> 
<P>5. PhoneInterfaceManager.java ( /packages/apps/Phone/src/com/android/phone/PhoneInterfaceManager.java ) <BR> 
</P> 
<P> see PhoneInterfaceManager the enableApnType Methods: </P> 
<P><PRE class=java name="code"> public int enableApnType(String type) { 
enforceModifyPermission(); 
return mPhone.enableApnType(type); 
} 
</PRE><P></P> 
 This will connect apn The request is sent to telephony The frame goes down. apn It's specified in the Settings app, 1 Generally in your project directory system/etc/apns-conf.xml file <BR> 
<BR> 
<P>6.  The above mPhone is PhoneProxy Object, </P> 
<P> Invocation process: </P> 
<P>PhoneProxy.java:<BR> 
</P> 
<P><PRE class=java name="code">mActivePhone.enableApnType(type)</PRE>mActivePhone is GSMPhone or CDMAPhone Upstream interface of PhoneBase object <BR> 
<P></P> 
<P>PhoneBase.java:</P> 
<P><PRE class=java name="code">mDataConnection.enableApnType(type);</PRE><P></P> 
<P> Calls to the  DataConnectionTracker the enableApnType methods </P> 
<P>DataConnectionTracker.java:<BR> 
</P> 
<P>enableApnType(String type)->setEnabled->onEnableApn->onEnableNewApn<BR> 
</P> 
<BR> 
<P>onEnableNewApn Methods in the DataConnectionTracker The derived class GsmDataConnectionTracker and CdmaDataConnectionTracker In order to distinguish the different types PHONE Data connection flow. <BR> 
</P> 
<P> In order to GSM For example, the invocation process: onEnableNewApn->cleanUpConnection->conn.disconnect<BR> 
<BR> 
</P> 
conn is DataConnection Object, identity 1 The clock data connection, you can see that this is actually implemented 1 Data connection state machine. <BR> 
<P> in DataConnection The state of the data connection in the object is divided into :</P> 
<P><PRE class=java name="code">DcDefaultState , the default state.  
DcInactiveState Inactive.  
DcActivatingState Is activated  
DcActiveState , active state  
DcDisconnectingState , is disconnecting  
DcDisconnectingBadDnsState , disconnected from state (because of error DNS )  
</PRE><P></P> 
<P> After the connection is successful, notifyDefaultData Calls to the DefaultPhoneNotifier the notifyDataConnection Methods. </P> 
<P>DefaultPhoneNotifier is ITelephonyRegistry The client side of the interface whose server side is TelephonyRegistry ( com.android.server.TelephonyRegistry ) </P> 
<P>TelephonyRegistry the notifyDataConnection The method is called in the following statement <BR> 
<PRE class=java name="code"> r.callback.onDataConnectionStateChanged(state, networkType);</PRE><P></P> 
<P>r Is the current mRecords Contains the elements of IPhoneStateListener Implementation of interface callback . TelephonyRegistry Each of the calls in the mRecords If an element registers a corresponding answer, </P> 
<P> The call callback Some function of. </P> 
<P> The client invokes the monitor to obtain the phone status in the following way.   In order to StatusBarPolicy.java In the mPhoneStateListener For example: </P> 
<P>            ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))</P> 
<P>                    .listen(mPhoneStateListener,<BR> 
                              PhoneStateListener.LISTEN_SERVICE_STATE<BR> 
                            | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS<BR> 
                            | PhoneStateListener.LISTEN_CALL_STATE<BR> 
                            | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE<BR> 
                            | PhoneStateListener.LISTEN_DATA_ACTIVITY);<BR> 
</P> 
<P>mPhoneStateListener is PhoneStateListener Instance, PhoneStateListener To achieve the IPhoneStateListener Interface, if you inherit PhoneStateListener Subclass, first you have to identify the listener you are interested in </P> 
<P> Event, and then override the corresponding method. Call it again like above listen The method is ok. </P> 
<P>TelephonyRegistry The corresponding relationship between the method, the monitoring action and the method you want to override is as follows: </P> 
<P>TelephonyRegistry The method of   --------------------- Monitor actions -------------------------------------------------------PhoneStateListener Callbacks in subclasses <BR> 
</P> 
<P>notifyServiceState   ---------- PhoneStateListener.LISTEN_SERVICE_STATE       -----------------  public void onServiceStateChanged(ServiceState state) <BR> 
</P> 
<P>notifySignalStrength   ------- PhoneStateListener.LISTEN_SIGNAL_STRENGTHS     --------- --  public void onSignalStrengthsChanged(SignalStrength signalStrength)<BR> 
</P> 
<P>notifyCallState  ---------------- PhoneStateListener.LISTEN_CALL_STATE    -------------------------   public void onCallStateChanged(int state, String incomingNumber)<BR> 
</P> 
<P>notifyDataConnection ------- PhoneStateListener.LISTEN_DATA_CONNECTION_STATE    ---   public void onDataConnectionStateChanged(int state, int networkType)<BR> 
</P> 
<P>notifyDataActivity  -------------- PhoneStateListener.LISTEN_DATA_ACTIVITY -----------------------   public void onDataActivity(int direction)<BR> 
</P> 
<P> . </P> 
<P> So the whole call chain is: DefaultPhoneNotifier : notifyDataConnection --------- "  TelephonyRegistry  : notifyDataConnection--------- " </P> 
<P>PhoneStateListener.callback : onDataConnectionStateChanged -------------- " PhoneStateListener A subclass onDataConnectionStateChanged</P> 
<P> In addition to that, TelephonyRegistry There was a 1 a ACTION_ANY_DATA_CONNECTION_STATE_CHANGED Contains the details of the data connection. </P> 
<P><BR> 
 while Mobile Data Service The inside of the MobileDataStateTracker It's going to receive the action, by its BoadcastReceiver class MobileDataStateReceiver Extract the data connection information and set the state </P> 
<PRE class=java name="code">setDetailedState(DetailedState.CONNECTING, reason, apnName); 
</PRE> 
<P>MobileDataStateTracker Student: depending on the state ConnectivityService send EVENT_STATE_CHANGED The message. </P> 
<P>ConnectivityService call handleConnect To perform the hype, including closing data connections with lower priority than it, updating the status bar, and so on. <BR> 
</P> 
<P> There are still a lot of things that haven't been figured out yet. <BR> 
</P> 
<P><BR> 
</P> 
<P><BR> 
</P> 
<BR> 
<P><BR> 
<BR> 
</P> 

Related articles: