天天看點

android 系統資料業務---打開2資料業務打開

2資料業務打開

DcTracker的onTrySetupData調用流程圖如下,

android 系統資料業務---打開2資料業務打開

onTrySetupData方法如下,

protected boolean onTrySetupData(String reason) {
   if (DBG) log("onTrySetupData: reason=" + reason);
   setupDataOnConnectableApns(reason);//利用可連接配接的APN進行撥号
   return true;
}
           

setupDataOnConnectableApns方法如下,

private void setupDataOnConnectableApns(String reason) {
    setupDataOnConnectableApns(reason, RetryFailures.ALWAYS);
}
           

這裡RetryFailures.ALWAYS表示連網失敗話,會一直重試。

trySetupData主要根據目前終端的運作狀态,判斷架構是否應該繼續撥号。

setupData主要邏輯如下,

1,首先根據一些列的條件進行判斷,然後建立一個DataConnection對象,

if (dcac == null) {
   dcac = createDataConnection();
}
           

2,建立成功後,更新狀态,

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 = apnContext;
//調用DcAsyncChannel的bringUp函數進行撥号上網
dcac.bringUp(apnContext, getInitialMaxRetry(), profileId, radioTech, mAutoAttachOnCreation,
                msg);
           

首先調用createDataConnection方法構造DataConnection和DcAsyncChannel對象,

然後調用調用DcAsyncChannel的bringUp函數進行撥号上網。

2.1 createDataConnection

createDataConnection的調用流程圖如下,

android 系統資料業務---打開2資料業務打開

createDataConnection方法如下,

private DcAsyncChannel createDataConnection() {
   if (DBG) log("createDataConnection E");
      //每個DataConnection有唯一的id号
int id = mUniqueIdGenerator.getAndIncrement();
    DataConnection conn = DataConnection.makeDataConnection(mPhone, id,
                      this, mDcTesterFailBringUpAll, mDcc);
mDataConnections.put(id, conn);
 //建立DcAsyncChannel
DcAsyncChannel dcac = new DcAsyncChannel(conn, LOG_TAG);
//完成dctracker與dataconnection之間handler的綁定
    int status = dcac.fullyConnectSync(mPhone.getContext(), this, conn.getHandler());
    if (status == AsyncChannel.STATUS_SUCCESSFUL) {
       mDataConnectionAcHashMap.put(dcac.getDataConnectionIdSync(), dcac);
    } else {
       loge("createDataConnection: Could not connect to dcac=" + dcac + " status=" + status);
     }
     if (DBG) log("createDataConnection() X id=" + id + " dc=" + conn);
     return dcac;
}
           

其實就是建立了2個對象, DataConnection和DcAsyncChannel,然後将2個對象通過Handler綁定,主要是為了通信。

1,建立DataConnection

DataConnection的makeDataConnection方法如下,

static DataConnection makeDataConnection(PhoneBase phone, int id,
      DcTrackerBase dct, DcTesterFailBringUpAll failBringUpAll, DcController dcc) {
   DataConnection dc = new DataConnection(phone,
                "DC-" + mInstanceNumber.incrementAndGet(), id, dct, failBringUpAll, dcc);
   dc.start();
   if (DBG) dc.log("Made " + dc.getName());
   return dc;
}
           

首先構造DataConnection對象, DataConnection其實是一個狀态機, DataConnection類的定義如下,

這個狀态機有7種狀态,初始狀态為

addState(mDefaultState);//預設狀态
addState(mInactiveState, mDefaultState);//未激活狀态
addState(mActivatingState, mDefaultState);//正在激活狀态
addState(mRetryingState, mDefaultState);//嘗試激活狀态
addState(mActiveState, mDefaultState);//已激活狀态
addState(mDisconnectingState, mDefaultState);//正在斷開狀态
addState(mDisconnectingErrorCreatingConnection, mDefaultState);//錯誤狀态
setInitialState(mInactiveState);//初始狀态
           

狀态機構造完成之後,就啟動狀态機。

2,建立DcAsyncChannel對象,并綁定

DcAsyncChannel定義如下,

DcAsyncChannel繼承于AsyncChannel,其詳細原理請見····

2.2撥号過程

DcAsyncChannel的bringUp方法直接發送消息,

sendMessage(DataConnection.EVENT_CONNECT,
           new ConnectionParams(apnContext, initialMaxRetry, profileId,
                            rilRadioTechnology, retryWhenSSChange, onCompletedMsg));
           

直接回調DataConnection狀态機的processMessage方法, DataConnection有6個狀态,調用哪個的

processMessage方法呢?上個小結中說過,初始狀态為DcInactiveState,是以直接調用DcInactiveState

的processMessage方法,對EVENT_CONNECT消息的處理如下,

ConnectionParams cp = (ConnectionParams) msg.obj;//擷取消息
if (initConnection(cp)) {
     onConnect(mConnectionParams);//進行撥号
     transitionTo(mActivatingState);//進入ActivatingState狀态
} else {
    •••
    notifyConnectCompleted(cp, DcFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
                                false); //通知DcTracker撥号失敗
}
retVal = HANDLED;
break;
           

首先調用onConnect進行撥号,然後調用transitionTo方法進入ActivatingState狀态。

onConnect方法主要邏輯如下,

Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
msg.obj = cp; // 建構Message對象
•••
//利用DcAsyncChannel傳輸的ConnectionParams資訊調用RIL的setupDataCall進行撥号
mPhone.mCi.setupDataCall(Integer.toString(cp.mRilRat + 2), Integer.toString(cp.mProfileId),
                mApnSetting.apn, mApnSetting.user, mApnSetting.password,
                Integer.toString(authType), protocol, msg);
           

RIL的setupDataCall方法如下,

setupDataCall(String radioTechnology, String profile, String apn,
            String user, String password, String authType, String protocol,
            Message result) {
        //構造RILRequest對象
        RILRequest rr
                = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
          //封裝消息
rr.mParcel.writeInt(7);
        rr.mParcel.writeString(radioTechnology);
        rr.mParcel.writeString(profile);
        rr.mParcel.writeString(apn);
        rr.mParcel.writeString(user);
        rr.mParcel.writeString(password);
        rr.mParcel.writeString(authType);
        rr.mParcel.writeString(protocol);
        if (RILJ_LOGD) riljLog(rr.serialString() + "> "
                + requestToString(rr.mRequest) + " " + radioTechnology + " "
                + profile + " " + apn + " " + user + " "
                + password + " " + authType + " " + protocol);
        send(rr); //調用send方法發送消息
    }
           

具體的RIL機制在此就不論述了,本文的重點不在于RIL機制,

隻需要知道的是當收到RIL_REQUEST_SETUP_DATA_CALL消息時, 将向DataConnection發送

EVENT_SETUP_DATA_CONNECTION_DONE的消息.