一、Android DcTracker的创建及准备工作

DcTracker是在每个Phone构造的时候创建的,DcTrackerBase是DcTracker,他们的核心都是Handler。

@GSMPhone.java  
public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {  
    //创建DcTracker对象,传递的参数就是当前的GSMPhone对象  
    mDcTracker = new DcTracker(this);  
}  

DcTracker作为数据链接中最重要的一个管理者核心,数据链接都会从DcTracker中发起,其中会做一些列的状态检查与判断,DcTracker处于的环节如下图中的浅蓝色部分
这里写图片描述
首先看DcTracker的构造

public DcTracker(PhoneBase p) { 
    super(p);

    mDataConnectionTracker = this;
    update();
    mApnObserver = new ApnChangeObserver();
    p.getContext().getContentResolver().registerContentObserver(
            Telephony.Carriers.CONTENT_URI, true, mApnObserver);

    initApnContexts();

    for (ApnContext apnContext : mApnContexts.values()) {
        // Register the reconnect and restart actions.
        IntentFilter filter = new IntentFilter();
        filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
        filter.addAction(INTENT_RESTART_TRYSETUP_ALARM + '.' + apnContext.getApnType());
        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
    }

    // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
    initEmergencyApnSetting();
    addEmergencyApnSetting();

    mProvisionActionName = "com.android.internal.telephony.PROVISION" + p.getPhoneId();
}    

首先调用的是update(),这里注册了大量的监听事件,并注册了APN参数的监听器

public void update() {  
     if (isActiveDataSubscription()) {  
         //注册各种监听器  
         registerForAllEvents(); 
         //注册SIM卡状态监听器  
         onUpdateIcc();
         //mUserDataEnabled就是用户是否打开网络开关的标志位,当为0时,表示当前数据流量被关闭  
         mUserDataEnabled = Settings.Global.getInt(mPhone.getContext().getContentResolver(), Settings.Global.MOBILE_DATA, 1) == 1;  
     }
 }   

接下来继续来看registerForAllEvents()和onUpdateIcc()中注册的事件类型

protected void registerForAllEvents() {  
    //监听射频是否打开,没有处理动作  
    mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);  
    //监听射频是否可用,没有处理动作  
    mPhone.mCi.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);  
    //监听当前连接状态,没有处理动作  
    mPhone.mCi.registerForDataNetworkStateChanged(this, DctConstants.EVENT_DATA_STATE_CHANGED, null);  
    //监听当前通话状态,没有处理动作  
    mPhone.getCallTracker().registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED, null);  
    //监听当前通话状态,没有处理动作  
    mPhone.getCallTracker().registerForVoiceCallStarted (this, DctConstants.EVENT_VOICE_CALL_STARTED, null);  
    //监听是否PS域Attach状态  
    mPhone.getServiceStateTracker().registerForDataConnectionAttached(this, DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);  
    //监听是否PS域Detach状态  
    mPhone.getServiceStateTracker().registerForDataConnectionDetached(this, DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);  
    //监听漫游状态,没有处理动作  
    mPhone.getServiceStateTracker().registerForRoamingOn(this, DctConstants.EVENT_ROAMING_ON, null);  
    //监听漫游状态,没有处理动作  
    mPhone.getServiceStateTracker().registerForRoamingOff(this, DctConstants.EVENT_ROAMING_OFF, null);  
    mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this, DctConstants.EVENT_PS_RESTRICT_ENABLED, null);  
    mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this, DctConstants.EVENT_PS_RESTRICT_DISABLED, null);  
    //监听接入技术状态  
    mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this, DctConstants.EVENT_DATA_RAT_CHANGED, null);  
}  

registerForAllEvents()注册了大量的事件,但是其中最重要的事件是EVENT_DATA_CONNECTION_ATTACHED
—-监听PS的Attach事件(代码中看出来应该是DataRegState的状态由STATE_OUT_OF_SERVICE -> STATE_IN_SERVICE),触发时将进入onDataConnectionAttached()

protected void onUpdateIcc() {  
   if (mUiccController == null ) {  
       return;  
   }  
   IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);  
   IccRecords r = mIccRecords.get();  
   if (r != newIccRecords) {  
       if (r != null) {  
           r.unregisterForRecordsLoaded(this);  
           mIccRecords.set(null);  
       }  
       if (newIccRecords != null) {  
           mIccRecords.set(newIccRecords);  
           //监听SIM各项数据是否载入完毕  
           newIccRecords.registerForRecordsLoaded( this, DctConstants.EVENT_RECORDS_LOADED, null);  
       }  
   }  
}  

其中注册了EVENT_RECORDS_LOADED事件,这个事件在SIM卡被装载完成后被通知
紧接着在DcTracker的构造中注册了APN参数变化的监听器,在用户手动切换选择APN时这个监听器会相应,将当前的APN参数更新为用户选择的APN参数

mApnObserver = new ApnChangeObserver();
p.getContext().getContentResolver().registerContentObserver(
Telephony.Carriers.CONTENT_URI, true, mApnObserver);

接下来在initApnContexts()中会初始化好当前系统支持的ApnContexts类型,并增加紧急APN,至此DcTracker的构造就完成了,在DcTrackerBase中还会创建一些与DataConnection有关的对象,接下来看DcTrackerBase的构造内容

protected DcTrackerBase(PhoneBase phone) {
    super();
    mPhone = phone;
    mResolver = mPhone.getContext().getContentResolver();
    mUiccController = UiccController.getInstance();
    mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
    mAlarmManager =
            (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
    mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
            Context.CONNECTIVITY_SERVICE);   //拿到ConnectivityManager

    mUserDataEnabled = getDataEnabled();

    mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 

    HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
    dcHandlerThread.start();
    Handler dcHandler = new Handler(dcHandlerThread.getLooper());
    mDcc = DcController.makeDcc(mPhone, this, dcHandler);
    mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
}

其中mResolver = mPhone.getContext().getContentResolver();是拿到ContentResolver,查询数据库就是通过这个对象去操作的,比如后面的mUserDataEnabled = getDataEnabled();
mUserDataEnabled是保存在settings.db数据库中表global中的mobile_data字段

public boolean getDataEnabled() {
    boolean retVal = "true".equalsIgnoreCase(SystemProperties.get(
            "ro.com.android.mobiledata", "true"));
    try {
        if (TelephonyManager.getDefault().getSimCount() == 1) {  //单卡path
            retVal = Settings.Global.getInt(mResolver, Settings.Global.MOBILE_DATA,
                    retVal ? 1 : 0) != 0;
        } else {
            int phoneSubId = mPhone.getSubId();                  //多卡path
            retVal = TelephonyManager.getIntWithSubId(mResolver, Settings.Global.MOBILE_DATA,
                    phoneSubId) != 0;
        }
        if (DBG) log("getDataEnabled: getIntWithSubId retVal=" + retVal);
    } 
    return retVal;
}

顺便提一下这个字段(settings.db数据库中表global中的mobile_data字段)的更新在DcTrackerBase.java中的onSetUserDataEnabled(boolean enabled)

protected void onSetUserDataEnabled(boolean enabled) {
    if (TelephonyManager.getDefault().getSimCount() == 1) {
        Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
    } else {
         int phoneSubId = mPhone.getSubId();
         Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA + phoneSubId,
                enabled ? 1 : 0);
    }
}

其中 mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);注册EVENT_ICC_CHANGED事件,当SIM卡发生改变时触发
其中 mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 注册一些Intent事件,比如当手机屏幕关闭时,就会关闭数据上下行的统计,等等
接下来是比较重要的一部分,在这里只是new HandlerThread,并创建了一个新的Handler放入DcController,创建了DcController对象,在后续中还会仔细分析这个Handler

    HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
    dcHandlerThread.start();
    Handler dcHandler = new Handler(dcHandlerThread.getLooper());
    mDcc = DcController.makeDcc(mPhone, this, dcHandler);
    mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);

至此,DcTracker算是完成了构造过程,接下来分析数据链接的动态过程

猜你喜欢

转载自blog.csdn.net/xiabodan/article/details/53765448