背景
以下內(nèi)容基于Android P code。
應(yīng)用框架設(shè)計
Android電話模塊是一個典型的分層結(jié)構(gòu)設(shè)計妆棒,如下:
IMS在CS通話的基礎(chǔ)上增加了telephony/ims net/ims vendor/ims 和ims相關(guān)的media模塊糕珊。
其中:
telephony/ims:主要包括了對外接口ImsPhone红选,通話管理中心ImsPhoneCallTracker喇肋,某一路通話ImsPhoneCall苟蹈,某一路通話連接ImsPhoneConnection右核。需要實現(xiàn)的提供IMS相關(guān)服務(wù)的ImsService贺喝。
net/ims:主要包括提供了IMS services API的ImsManager,以及ImsManager創(chuàng)建的負責(zé)處理 IMS語音和視頻通話連接的ImsCall殷绍。
vendor/ims:主要包括了ImsService的實現(xiàn)類鹊漠,提供ims相關(guān)的服務(wù)躯概。負責(zé)和modem和media打交道娶靡,這一模塊由各個芯片廠商定制,所以各個芯片廠商的實現(xiàn)方式都不同塔鳍。但都有一個實現(xiàn)?ImsService的類轮纫。
IMS service
IMS的服務(wù)類蜡感,telephony通過ImsResolver來和綁定它。它的實現(xiàn)類必需在AndroidManifest中對它進行注冊以便fw檢測到它贝乎。
其主要結(jié)構(gòu)如下:
主要包括 ImsService览效、ImsManager锤灿、MmTelFeatureConnection但校、ImsCallSession啡氢。其中:
ImsService:ims的Service,實現(xiàn)了所有的ImsFeature(MmTelFeature和RcsFeature)和ims協(xié)議行為袭艺。通過ImsResolver綁定猾编。由ImsServiceController來負責(zé)管理其生命周期及這個service所支持的ImsFeatures答倡。其主要操作可以通過IImsServiceController來調(diào)用冻晤。
ImsManager:單例類鼻弧。提供了與IMS services交互的API攘轩,如創(chuàng)建ims call度帮。這個類是所有ims相關(guān)操作的起點笨篷。
MmTelFeatureConnection:IImsServiceController binder的容器類。
ImsCallSession:負責(zé)ImsCall的發(fā)起和終止练俐,以及兩個ims端點間的媒體交換腺晾。它和ImsService直接交互悯蝉。
其service的綁定過程如下:
可以看到鼻由,phone進程在創(chuàng)建后由ImsResolver通過ImsServiceController來綁定service嗡靡,service返回IImsServiceController給ImsServiceController讨彼,然后通過這個binder來創(chuàng)建IImsMmTelFeature的binder。之后可以通過TelephonyManager來獲取IImsMmTelFeature的binder哈误,用它可以獲取IImsCallSession的binder哩至。
具體的綁定流程如下:
應(yīng)用間進程交互
交互方式如下:
在android o之前phone和ril的交互是通過socket,android o之后改成了HIDL蜜自。其余進程間的交互都是通過AIDL菩貌,具體交互方式如圖:
其中,phone到modem的過程重荠,CS Call是由RILRequest通過HIDL調(diào)用IRadio.hal再到modem箭阶,IMS Call是由ImsCallSession通過AIDL調(diào)用ImsCallSessionImpl再通過HIDL調(diào)用IImsRadio.hal再到modem戈鲁。而modem到phone的過程仇参,CS Call是由IRadioResponse.hal通過HIDL非主動上報結(jié)果給RadioResponse,而IRadioIndication.hal通過HIDL主動上報通知給RadioIndication婆殿,IMS Call則是從hal上報到Ims service诈乒,再通過ImsCallSessionListener通知到ImsCallSession。
總的來說就是IMS Call比CS Call在phone進程和ril hal中多了一層ims service婆芦。
通話流程
IMS Call結(jié)構(gòu)
先看CS Call和IMS Call的結(jié)構(gòu)對比:
從圖中可以看出怕磨,其實整體的設(shè)計模式差不多。其對比如下:
1. 對外接口GsmCdmaPhone對應(yīng)ImsPhone消约。
2. 一路通話的封裝類GsmCdmaCall對應(yīng)ImsPhoneCall肠鲫。
3. 通話中的某路連接GsmCdmaConnection對應(yīng)ImsPhoneConnection。
4. modem返回回來的某一路通話連接DriverCall對應(yīng)ImsCall或粮。
5. CS Call phone 通過IRadio滩届、IRadioResponse、IRadioIndication和RIL交互被啼。
6. IMS Call phone 通過IImsCallSession、IImsCallSessionListener棠枉、IImsMmTelListener和ims service交互浓体。
IMS Call MO流程
先看IMS和CS的對比:
可以看到CallTracker撥號之前的過程兩者一樣,CallTracker撥號時CS Call直接通過RIL用HIDL來調(diào)用IRadio.hal撥號辈讶;而IMS Call需要由ImsManager通過ImsCallSession用AIDL調(diào)用ImsCallSessionImpl命浴,再通過HIDL調(diào)用IImsRadio.hal來撥號,比CS Call多了ims service進程中的處理。
CallTracker撥號之前的過程可以參考我之前的文章?Android通話應(yīng)用設(shè)計生闲,其大致流程沒有變媳溺。這里補充一下telecom進程撥號的具體細節(jié)如下:
其大至流程就是:
1. 撥號應(yīng)用如Dialer調(diào)用TelecomManager#placeCall()。
2. CallsManager#startOutgoingCall()創(chuàng)建Call碍讯,并設(shè)置Call狀態(tài)為Connecting悬蔽。判斷是否mmi code,如果不是通知InCallUI更新界面捉兴。
3. 發(fā)送order broadcast給接收該廣播的應(yīng)用更改號碼相關(guān)信息蝎困。
4. CallsManager#placeOutgoingCall()根據(jù)intent中所帶參數(shù)判斷該通電話是否為視頻電話.
5. 建立同ConnectionService的連接,通知TelephonyConnectionService撥號倍啥。
6.?TelephonyConnectionService通知撥號成功禾乘,更新Call狀態(tài)為Dialing。
其中IMS Call增加的流程就是在撥號時的intent中帶參數(shù)配置該通電話是否為視頻電話虽缕,然后把這個videoState一直傳遞下去始藕。
IMS Call 狀態(tài)變更流程
先看IMS和CS的對比:
和MO一樣,IMS Call多了ims service這一部分氮趋,而CS Call 多了GET_CURRENT_CALLS的過程伍派。
其中的重點部分是IMS Call 中的ImsPhoneCallTracker#processCallStateChange()及CS Call 中的GsmCdmaCallTracker#handlePollCalls()。
和app相關(guān)的流程請參考?Android通話應(yīng)用設(shè)計凭峡。
IMS Call MT流程
先看IMS和CS的對比:
其對比如下:
1.?CS Call 在收到RadioIndication上報的callStateChanged()后會通過GET_CURRENT_CALL來更新DriverCall拙已,?然后在GsmCdmaCallTracker#handlePollCalls()中通過DriverCall來更新Connection并通知app來電。
2. IMS Call 中會在ImsPhoneCallTracker#onIncomingCall()中通過ImsCallSession來創(chuàng)建ImsCall連接摧冀,并創(chuàng)建Connection倍踪,創(chuàng)建Connection時會通過IImsCallSession里帶的參數(shù)判斷通話是否為視頻通話。
app來電后的流程可參考?Android通話應(yīng)用設(shè)計,這里補充telecom app 來電的流程种蝶,如下:
1. telephony收到來電通知時根據(jù)來電的phone找到PhoneAccountHandle丹喻,通話TelecomManager#processIncomingCallIntent()通知telecom來電。
2. CallsManager#processIncomingCallIntent()創(chuàng)建Call缤至,并建立和ConnectionService的連接。
3. ConnectionService返回連接成功康谆,通過phone進程中的Connection更新telecom/Call领斥,包括是否視頻電話。
4. CallsManager#onSuccessfulIncomingCall()開始號碼過濾查詢(包括黑名單查詢)沃暗,如果是過濾號碼來電直接拒接月洛。
5. 如果是非過濾號碼來電更新Call狀態(tài)為RINGING。
6. 通過InCallController建立與通話界面的連接孽锥,更新通話界面嚼黔。
MMI Code 流程
MMI:Man-Machine-Interface细层,人機界面,所有帶*或#的號碼都是MMI Code唬涧。通常以*疫赎、#、*#碎节、**捧搞、##等開頭,以#號結(jié)束钓株,各個部分以*隔開实牡。它們有些僅在設(shè)備上使用,有些發(fā)送給sim卡處理轴合,有些則發(fā)給運營商網(wǎng)絡(luò)處理创坞。它主要分為:
1. USSD:Unstructured Supplementary Service Data,非結(jié)構(gòu)化補充服務(wù)數(shù)據(jù)碼受葛,發(fā)送給網(wǎng)絡(luò)處理题涨。所有以#號結(jié)尾且沒有被識別為MMI Code的號碼都會被發(fā)送到網(wǎng)絡(luò)來確認該號碼是否為運營商支持的USSD。
2. SS:Supplementary Service总滩,補充服務(wù)碼纲堵,發(fā)送給網(wǎng)絡(luò)處理。如*21*xxx xxxx xxxx#為GSM/UMTS/LTE網(wǎng)絡(luò)的來電轉(zhuǎn)接碼闰渔,這個號碼會由手機轉(zhuǎn)換成網(wǎng)絡(luò)可識別的來電轉(zhuǎn)接碼席函。
3. Manufacturer defined MMI codes:手機廠商自定義的mmi碼,在設(shè)備上執(zhí)行冈涧。如通用的*#06#會顯示手機IMEI號茂附。各家手機廠商也可以定義自己的mmi碼來做為暗碼,它的處理一般在Dialer/SpeciaCharSequenceMgr中督弓。
4. SIM control codes:sim卡控制碼营曼,發(fā)送給sim卡處理。如**04*1234*6789*6789#會把sim卡的pin碼從1234改成6789愚隧。
MMI code 分主動上報和非主動上報兩種蒂阱,下圖為非主動手報流程:
1. 手機自己處理的mmi碼一般直接通過Dialer處理。
2. 發(fā)送給sim卡處理的碼通過Dialer直接傳到GsmMmiCode給UiccCardApplication再由IRadio.hal處理狂塘,其處理結(jié)果會在PhoneUtils#displayMMIComplete()顯示給用戶录煤。
3. 發(fā)送給網(wǎng)絡(luò)處理的碼則和正常撥號一樣,只不過telecom在判斷其為mmi code后不會通知InCallUI荞胡,CallTracker#dial()后返回空的Connection給phone app通知其彈出對話框提示用戶正在進行MMI碼的處理妈踊。
4. 會先判斷該mmi code是不是ims網(wǎng)絡(luò)的碼,如果是直接由ims網(wǎng)絡(luò)處理硝训,如果不是則由gsm/umts/lte網(wǎng)絡(luò)處理。
5. SS code手機能直接判斷出,然后轉(zhuǎn)換為網(wǎng)絡(luò)能識別的命令發(fā)送給網(wǎng)絡(luò)窖梁,CS Call和通話一樣由IRadio.hal處理赘风,而IMS Call則不是由IImsCallSession處理而是通過IImsUt處理。USSD code直接透傳給網(wǎng)絡(luò)處理纵刘。網(wǎng)絡(luò)處理結(jié)果CS Call和通話狀態(tài)一樣直接由IRadioResponse.hal通知邀窃,IMS Call則由IImsUtListener通知。
原創(chuàng)內(nèi)容歡迎轉(zhuǎn)載假哎,但請注明出處瞬捕,謝謝!