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算是完成了構造過程,接下來分析數據鏈接的動態過程