Android IMS 通话应用设计

背景

以下内容基于Android P code。

应用框架设计

Android电话模块是一个典型的分层结构设计,如下:

分层结构

IMS在CS通话的基础上增加了telephony/ims net/ims vendor/ims 和ims相关的media模块。

其中:

telephony/ims:主要包括了对外接口ImsPhone,通话管理中心ImsPhoneCallTracker,某一路通话ImsPhoneCall,某一路通话连接ImsPhoneConnection。需要实现的提供IMS相关服务的ImsService。

net/ims:主要包括提供了IMS services API的ImsManager,以及ImsManager创建的负责处理 IMS语音和视频通话连接的ImsCall。

vendor/ims:主要包括了ImsService的实现类,提供ims相关的服务。负责和modem和media打交道,这一模块由各个芯片厂商定制,所以各个芯片厂商的实现方式都不同。但都有一个实现 ImsService的类。

IMS service

IMS的服务类,telephony通过ImsResolver来和绑定它。它的实现类必需在AndroidManifest中对它进行注册以便fw检测到它。

其主要结构如下:

扫描二维码关注公众号,回复: 11144196 查看本文章

ims service 结构

主要包括 ImsService、ImsManager、MmTelFeatureConnection、ImsCallSession。其中:

ImsService:ims的Service,实现了所有的ImsFeature(MmTelFeature和RcsFeature)和ims协议行为。通过ImsResolver绑定。由ImsServiceController来负责管理其生命周期及这个service所支持的ImsFeatures。其主要操作可以通过IImsServiceController来调用。

ImsManager:单例类。提供了与IMS services交互的API,如创建ims call。这个类是所有ims相关操作的起点。

MmTelFeatureConnection:IImsServiceController binder的容器类。

ImsCallSession:负责ImsCall的发起和终止,以及两个ims端点间的媒体交换。它和ImsService直接交互。

其service的绑定过程如下:

ims service bind

可以看到,phone进程在创建后由ImsResolver通过ImsServiceController来绑定service,service返回IImsServiceController给ImsServiceController,然后通过这个binder来创建IImsMmTelFeature的binder。之后可以通过TelephonyManager来获取IImsMmTelFeature的binder,用它可以获取IImsCallSession的binder。

具体的绑定流程如下:

ims service bind详解

应用间进程交互

交互方式如下:

ims 进程交互

在android o之前phone和ril的交互是通过socket,android o之后改成了HIDL。其余进程间的交互都是通过AIDL,具体交互方式如图:

ims 进程交互细节

其中,phone到modem的过程,CS Call是由RILRequest通过HIDL调用IRadio.hal再到modem,IMS Call是由ImsCallSession通过AIDL调用ImsCallSessionImpl再通过HIDL调用IImsRadio.hal再到modem。而modem到phone的过程,CS Call是由IRadioResponse.hal通过HIDL非主动上报结果给RadioResponse,而IRadioIndication.hal通过HIDL主动上报通知给RadioIndication,IMS Call则是从hal上报到Ims service,再通过ImsCallSessionListener通知到ImsCallSession。

总的来说就是IMS Call比CS Call在phone进程和ril hal中多了一层ims service。

通话流程

IMS Call结构

先看CS Call和IMS Call的结构对比:

call 结构对比

从图中可以看出,其实整体的设计模式差不多。其对比如下:

1. 对外接口GsmCdmaPhone对应ImsPhone。

2. 一路通话的封装类GsmCdmaCall对应ImsPhoneCall。

3. 通话中的某路连接GsmCdmaConnection对应ImsPhoneConnection。

4. modem返回回来的某一路通话连接DriverCall对应ImsCall。

5. CS Call phone 通过IRadio、IRadioResponse、IRadioIndication和RIL交互。

6. IMS Call phone 通过IImsCallSession、IImsCallSessionListener、IImsMmTelListener和ims service交互。

IMS Call MO流程

先看IMS和CS的对比:

MO 对比

可以看到CallTracker拨号之前的过程两者一样,CallTracker拨号时CS Call直接通过RIL用HIDL来调用IRadio.hal拨号;而IMS Call需要由ImsManager通过ImsCallSession用AIDL调用ImsCallSessionImpl,再通过HIDL调用IImsRadio.hal来拨号,比CS Call多了ims service进程中的处理。

CallTracker拨号之前的过程可以参考我之前的文章 Android通话应用设计,其大致流程没有变。这里补充一下telecom进程拨号的具体细节如下:

其大至流程就是:

telecom MO 流程

1. 拨号应用如Dialer调用TelecomManager#placeCall()。

2. CallsManager#startOutgoingCall()创建Call,并设置Call状态为Connecting。判断是否mmi code,如果不是通知InCallUI更新界面。

3. 发送order broadcast给接收该广播的应用更改号码相关信息。

4. CallsManager#placeOutgoingCall()根据intent中所带参数判断该通电话是否为视频电话.

5. 建立同ConnectionService的连接,通知TelephonyConnectionService拨号。

6. TelephonyConnectionService通知拨号成功,更新Call状态为Dialing。

其中IMS Call增加的流程就是在拨号时的intent中带参数配置该通电话是否为视频电话,然后把这个videoState一直传递下去。

IMS Call 状态变更流程

先看IMS和CS的对比:

状态变更对比

和MO一样,IMS Call多了ims service这一部分,而CS Call 多了GET_CURRENT_CALLS的过程。

其中的重点部分是IMS Call 中的ImsPhoneCallTracker#processCallStateChange()及CS Call 中的GsmCdmaCallTracker#handlePollCalls()。

和app相关的流程请参考 Android通话应用设计

IMS Call MT流程

先看IMS和CS的对比:

MT 对比

其对比如下:

1. CS Call 在收到RadioIndication上报的callStateChanged()后会通过GET_CURRENT_CALL来更新DriverCall, 然后在GsmCdmaCallTracker#handlePollCalls()中通过DriverCall来更新Connection并通知app来电。

2. IMS Call 中会在ImsPhoneCallTracker#onIncomingCall()中通过ImsCallSession来创建ImsCall连接,并创建Connection,创建Connection时会通过IImsCallSession里带的参数判断通话是否为视频通话。

app来电后的流程可参考 Android通话应用设计,这里补充telecom app 来电的流程,如下:

telecom 来电流程

1. telephony收到来电通知时根据来电的phone找到PhoneAccountHandle,通话TelecomManager#processIncomingCallIntent()通知telecom来电。

2. CallsManager#processIncomingCallIntent()创建Call,并建立和ConnectionService的连接。

3. ConnectionService返回连接成功,通过phone进程中的Connection更新telecom/Call,包括是否视频电话。

4. CallsManager#onSuccessfulIncomingCall()开始号码过滤查询(包括黑名单查询),如果是过滤号码来电直接拒接。

5. 如果是非过滤号码来电更新Call状态为RINGING。

6. 通过InCallController建立与通话界面的连接,更新通话界面。

MMI Code 流程

MMI:Man-Machine-Interface,人机界面,所有带*或#的号码都是MMI Code。通常以*、#、*#、**、##等开头,以#号结束,各个部分以*隔开。它们有些仅在设备上使用,有些发送给sim卡处理,有些则发给运营商网络处理。它主要分为:

1. USSD:Unstructured Supplementary Service Data,非结构化补充服务数据码,发送给网络处理。所有以#号结尾且没有被识别为MMI Code的号码都会被发送到网络来确认该号码是否为运营商支持的USSD。

2. SS:Supplementary Service,补充服务码,发送给网络处理。如*21*xxx xxxx xxxx#为GSM/UMTS/LTE网络的来电转接码,这个号码会由手机转换成网络可识别的来电转接码。

3. Manufacturer defined MMI codes:手机厂商自定义的mmi码,在设备上执行。如通用的*#06#会显示手机IMEI号。各家手机厂商也可以定义自己的mmi码来做为暗码,它的处理一般在Dialer/SpeciaCharSequenceMgr中。

4. SIM control codes:sim卡控制码,发送给sim卡处理。如**04*1234*6789*6789#会把sim卡的pin码从1234改成6789。

MMI code 分主动上报和非主动上报两种,下图为非主动手报流程:

solicited mmi code

1. 手机自己处理的mmi码一般直接通过Dialer处理。

2. 发送给sim卡处理的码通过Dialer直接传到GsmMmiCode给UiccCardApplication再由IRadio.hal处理,其处理结果会在PhoneUtils#displayMMIComplete()显示给用户。

3. 发送给网络处理的码则和正常拨号一样,只不过telecom在判断其为mmi code后不会通知InCallUI,CallTracker#dial()后返回空的Connection给phone app通知其弹出对话框提示用户正在进行MMI码的处理。

4. 会先判断该mmi code是不是ims网络的码,如果是直接由ims网络处理,如果不是则由gsm/umts/lte网络处理。

5. SS code手机能直接判断出,然后转换为网络能识别的命令发送给网络,CS Call和通话一样由IRadio.hal处理,而IMS Call则不是由IImsCallSession处理而是通过IImsUt处理。USSD code直接透传给网络处理。网络处理结果CS Call和通话状态一样直接由IRadioResponse.hal通知,IMS Call则由IImsUtListener通知。



作者:朱兰婷
链接:https://www.jianshu.com/p/bdb0171f1540
 

原创文章 113 获赞 190 访问量 130万+

猜你喜欢

转载自blog.csdn.net/dxpqxb/article/details/104315936