整個資料連線過程主要靠DataConnection及其對應cdma和gsm的子類
資料連線包含幾種狀態,建構函式裡面必須添加這幾種狀態,並且指定一個初始狀態,如下代碼
293 addState(mDefaultState);
294 addState(mInactiveState, mDefaultState);
295 addState(mActivatingState, mDefaultState);
296 addState(mActiveState, mDefaultState);
297 addState(mDisconnectingState, mDefaultState);
298 addState(mDisconnectingBadDnsState, mDefaultState);
299 setInitialState(mInactiveState);
設定初始化狀態為mInactiveState,意思是未啟用的串連
private DcInactiveState mInactiveState = new DcInactiveState();
所有的狀態類都是繼承自HierarchicalState,就像
private class DcInactiveState extends HierarchicalState
狀態之間可以相互轉換,可以接收訊息,進行串連斷開等操作
需要進行串連之時,調用
public void connect(Message onCompletedMsg, ApnSetting apn);或者
public void connect(Message onCompletedMsg),前者指定apn設定,後者為null
兩個方法都是向目前狀態發送訊息
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));或者
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(null, onCompletedMsg)));
mInactiveState收到訊息之後
554 case EVENT_CONNECT:
555 if (DBG) log("DcInactiveState msg.what=EVENT_CONNECT");
556 ConnectionParams cp = (ConnectionParams) msg.obj;
557 cp.tag = mTag;
558 onConnect(cp);
559 transitionTo(mActivatingState);
560 retVal = true;
561 break;
調用onConnect(cp),這是個abstract函數,在GsmDataConnection和CdmaDataConnection裡面得到了實現,在CdmaDataConnection的onConnect(cp)裡面,調用RIL.java裡面的方法:
98 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
99 msg.obj = cp;
101 phone.mCM.setupDataCall(Integer.toString(RILConstants.SETUP_DATA_TECH_CDMA),
102 Integer.toString(dataProfile), cp.apn.apn, cp.apn.user,
103 cp.apn.password, Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP), msg);
這樣,把請求發送到RIL層之後,轉換到mActivatingState狀態,接下來就是等待RIL層回應了
跟上一篇部落格學習RIL那樣,會形成一個非同步結果,綁定到訊息裡面發上來
AsyncResult.forMessage(rr.mResult, ret, null);
rr.mResult.sendToTarget();
而上面的mActivationState狀態會收到
589 case EVENT_SETUP_DATA_CONNECTION_DONE:
590 if (DBG) log("DcActivatingState msg.what=EVENT_SETUP_DATA_CONNECTION_DONE");
591
592 ar = (AsyncResult) msg.obj;
593 cp = (ConnectionParams) ar.userObj;
594
595 SetupResult result = onSetupConnectionCompleted(ar);
596 switch (result) {
597 case SUCCESS:
598 // All is well
599 mActiveState.setEnterNotificationParams(cp, FailCause.NONE);
600 transitionTo(mActiveState);
601 break;
602 case ERR_BadCommand:
603 // Vendor ril rejected the command and didn't connect.
604 // Transition to inactive but send notifications after
605 // we've entered the mInactive state.
606 mInactiveState.setEnterNotificationParams(cp, result.mFailCause);
607 transitionTo(mInactiveState);
608 break;
609 case ERR_BadDns:
610 // Connection succeeded but DNS info is bad so disconnect
611 EventLog.writeEvent(EventLogTags.PDP_BAD_DNS_ADDRESS, dnsServers[0]);
612 tearDownData(cp);
613 transitionTo(mDisconnectingBadDnsState);
614 break;
615 case ERR_Other:
616 // Request the failure cause and process in this state
617 phone.mCM.getLastDataCallFailCause(
618 obtainMessage(EVENT_GET_LAST_FAIL_DONE, cp));
619 break;
620 case ERR_Stale:
621 // Request is stale, ignore.
622 break;
623 default:
624 throw new RuntimeException("Unkown SetupResult, should not happen");
625 }
626 retVal = true;
627 break;