美文网首页
Android IMS 通话应用设计

Android IMS 通话应用设计

作者: 朱兰婷 | 来源:发表于2019-10-16 11:27 被阅读0次

    背景

    以下内容基于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检测到它。

    其主要结构如下:

    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通知。

    原创内容欢迎转载,但请注明出处,谢谢!

    相关文章

      网友评论

          本文标题:Android IMS 通话应用设计

          本文链接:https://www.haomeiwen.com/subject/jailmctx.html