天天看點

Android核心分析(19)----電話系統之GSMCallTackerAndroid電話系統之GSMCallTracker

Android電話系統之GSMCallTracker

通話連接配接管理

GSMCallTracker在本質上是一個Handler。

Android核心分析(19)----電話系統之GSMCallTackerAndroid電話系統之GSMCallTracker

GSMCallTracker是Android的通話管理層。GSMCallTracker建立了ConnectionList來管理現行的通話連接配接,并向上層提供電話調用接口。

Android核心分析(19)----電話系統之GSMCallTackerAndroid電話系統之GSMCallTracker

在GSMCallTracker中維護着通話清單:connections。順序記錄了正連接配接上的通話,這些通話包括:ACTIVE,DIALING,ALERTING,HOLDING,INCOMING,WAITING等狀态的連接配接。GSMCallTracker将這些連接配接分為了三類别進行管理:

RingingCall: INCOMING ,WAITING

ForegourndCall: ACTIVE, DIALING ,ALERTING

BackgroundCall: HOLDING

上層函數通過getRingCall(),getForegrouandCall()等來獲得電話系統中特定通話連接配接。

為了管理電話狀态,GSMCallTracker在構造時就将自己登記到了電話狀态變化通知表中。RIL-Java一收到電話狀态變化的通知,就會使用EVENT_CALL_STATE_CHANGE通知到GSMCallTacker

    在一般的實作中,我們的通話Call Table是通過AT+CLCC查詢到的,CPI可以通知到電話的改變,但是CPI在各個Modem的實作中差别比較大,是以參考設計都沒有用到CPI這樣的電話連接配接改變通知,而是使用最為傳統的CLCC查詢CALL TABLE。在GSMTracker中使用connections來管理Android電話系統中的通話連接配接。每次電話狀态發生變化是GSMTracker就會使用CLCC查詢來更新connections内容,如果内容有發生變化,則向上層發起電話狀态改變的通知。

1 RIL-JAVA中發起電話連接配接清單操作

在RIL-JAVA中涉及到CurrentCallList查詢的有以下幾個操作:

(1)hangup

(2)dial

(3)acceptCall

(4)rejectCall

在GSMcallTracker在發起這些調用的時候都有一個共同的ResultMessage構造函數:obtainCompleteMessage()。obtainCompleteMessage()實際上是調用:

obtainCompleteMessage(EVENT_OPERATION_COMPLETE)

這就意味着在這些電話操作後,GSMCallTracker會收到EVENT_OPERATION_COMPLETE消息,于是我們将目光轉移到handleMessage()@GSMCallTracker的EVENT_OPERATION_COMPLETE事件處理:[email protected]。

operationComplete()操作會使用cm.getCurrentCalls(lastRelevantPoll)調用,向RILD發起RIL_REQUEST_GET_CURRENT_CALLS調用,這個最終就是向Modem發起AT+CLCC,擷取到真正的電話清單。

2 在RILD中,引起getCurrentCalls調用

(1)在RILD中,收到URC消息:

+CRING

RING

NO CARRIER

+CCWA

将會使用RIL_onUnsolicitedResponse( RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED),主動向ril-java上報RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED消息。

(2) 在處理requestCurrentCalls時,使用CLCC查詢通話連接配接(CALL TABLE)後,如何發現有call Table不為空則開啟一個定時器,主動上報RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED消息,直到沒有電話連接配接為止。

在RIL-Java層收到RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED這個URC,并利用mCallStateRegistrants.notifyRegistrants(new AsyncResult(null, null, null))來通知電話狀态的變化,此時GSMTracker會接收到EVENT_CALL_STATE_CHANGE消息,并使用

                pollCallsWhenSafe()->  cm.getCurrentCalls(lastRelevantPoll);

來發起查詢,并更新JAVA層的電話清單。

3 handlePollCalls電話清單重新整理

      首先我們來看看是什麼引起了handlePollCalls的調用。

     上面的1,2分析了,Android電話系統中所有引起電話連接配接清單更新的條件及其處理。他們共同的調用了cm.getCurrentCalls(lastRelevantPoll) 來完成電話清單的擷取。

lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT)

我們這裡就從可以看到擷取到的電話清單Result使用handlePollCalls進行了處理。Result實際上是一個DriverCall清單,handlePollCalls的工作就是将目前電話清單與RIL-Java的電話清單對比,使用DriverCall清單更新CallTracker的電話清單connections,并向上傳遞電話狀态改變的通知。