本文主要讲解IP Multimedia Subsystem (IMS)在Android 7.0上由谷歌Android实现的部分内容。
从APP侧一直到Telephony Framework,是不区分CS流程还是PS流程的。到了Telephony Framework模块,会依据IMS相关的状态信息(Registration Status,Service Status等)和用户设置信息(Volte Enable?Wifi Calling Enable?UT Enable?等 )进而判断出,Call、SMS等是否需要优先走IMS的流程。
整体来看,IMS框架如下图:

通常都是由Phone对象或者ImsPhoneCallTracker对象直接得到ImsManager对象

mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());

接着再通过ImsManager对象间接地得到ImsConfig、ImsUt、ImsCall等重要对象,然后根据请求不同而走不同的通道与Vendor RIL通信,与Call相关的走ImsCall,与补充业务相关的走ImsUt,与IMS功能的能力、参数相关的走ImsConfig,所以分工是十分明确的。谷歌为了规范高通/MTK等芯片厂商的行为,所以定义了IImsService、IImsConfig、IImsCallSession和IImsUt等接口,再由各芯片厂商来实现这些接口,谷歌只需要处理好上层调用接口的逻辑即可。

接下来分别讲一下各个类

ImsPhone

ImsPhone是为了与CS Call区分开,用来处理IMS相关事务的Phone实例,以setCallWaiting为例:

    public void setCallWaiting(boolean enable, Message onComplete) {
if (isPhoneTypeGsm()) {
Phone imsPhone = mImsPhone;
//判断是否符合IMS的条件
if ((imsPhone != null)
&& ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
|| imsPhone.isUtEnabled())) {
//走IMS流程
imsPhone.setCallWaiting(enable, onComplete);
return;
}
//走CS流程
mCi.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
} else {
loge("method setCallWaiting is NOT supported in CDMA!");
}
}

然而仅仅有Phone实例是不够的,还需要有对应地CallTracker、Call以及Connection对象,所以就有了下面这张图:

ImsPhone实例是在IMS Service启动之后被创建的,接着会初始化ImsPhoneCallTracker对象。

ImsPhoneCallTracker

ImsPhoneCallTracker在初始化的时候会注册监听IMS InComing call

intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL);

同时将Action为“ACTION_IMS_INCOMING_CALL”的PendingIntent传递给IMS Service,这样子就可以监听到IMS MT Call了。

ImsPhoneCallTracker内部会初始化四个ImsPhoneCall对象,

    public ImsPhoneCall mRingingCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_RINGING);
public ImsPhoneCall mForegroundCall = new ImsPhoneCall(this,ImsPhoneCall.CONTEXT_FOREGROUND);
public ImsPhoneCall mBackgroundCall = new ImsPhoneCall(this,ImsPhoneCall.CONTEXT_BACKGROUND);
public ImsPhoneCall mHandoverCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_HANDOVER);

比GsmCdmaCallTracker多了一个Handover Call,比如VoWiFi与VoLTE相互切换就是通过Handover来实现的。

还有一点ImsPhoneCallTracker与GsmCdmaCallTracker不一样的就是

    protected void handlePollCalls(AsyncResult ar) { }

ImsPhoneCallTracker的handlePollCalls()方法是空的,是因为IMS Call状态消息的上报和获取modem当前Call List信息等这些逻辑需要高通/MTK来实现,ImsPhoneCallTracker则通过ImsCall.Listener来监听Ims Call的状态变化信息,然后再根据ImsCall的状态,更新当前ImsPhoneConnection与四种ImsPhoneCall的绑定关系。
比如:
1. A<—>B正在通话,这通电话对应的Connection会与mForegroundCall绑定;
2. 此时A再呼叫C,那么A<—>B这通电话的Connection就会先与mBackgroundCall绑定,这种切换是由mBackgroundCall与mForegroundCall互换Connection集合和状态实现的;

mForegroundCall.switchWith(mBackgroundCall);

3.然后A<—>C接通之后,A<—>C这通电话对应的Connection会与mForegroundCall绑定。
就是这样子。每个ImsPhoneCall最多绑定5个ImsPhoneConnection,这个值规定在ImsPhoneCallTracker中:

static final int MAX_CONNECTIONS_PER_CALL = 5;

ImsPhoneCallTracker还负责监听IMS service的状态变化

private ImsConnectionStateListener mImsConnectionStateListener =
new ImsConnectionStateListener() {
//IMS已注册上
public void onImsConnected() {}
//IMS已断开,有时候会上报断开的原因
public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {}
//IMS处于正在注册状态
public void onImsProgressing() {}
//"VoLTE", "ViLTE", "VoWiFi", "ViWiFi",
//"UTLTE", "UTWiFi"等功能的能力变化
public void onFeatureCapabilityChanged() {}
......
}

如果遇到IMS注册不上的问题,应该去看IMS注册时的SIP信令流程。

ImsManager

ImsManager作为IMS框架的核心,是任意IMS action的出发点。ImsManager的职责主要有以下3点:
1. 向上提供ImsConfig、ImsUt、ImsCall等重要对象,得到这些对象就可以跟Vendor RIL通信了。

 public ImsUtInterface getSupplementaryServiceConfiguration(){}
public ImsConfig getConfigInterface(){}
public ImsCall makeCall(){}

2 .向APP提供设置IMS相关功能的接口

//设置VoLTE打开或者关闭
public static void setVtSetting(Context context, boolean enabled) {}
//设置WiFi Calling打开或者关闭
public static void setWfcSetting(Context context, boolean enabled) {}
//设置WiFi Calling的模式,如WiFi Only、WiFi优先...
public static void setWfcMode(Context context, int wfcMode) {}
//设置4G LTE增强模式打开或者关闭
public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {}

3.向上传递IMS注册状态变化的消息,是由ImsManager来通知ImsPhoneCallTracker的。

ImsService

谷歌定义好了ImsServiceBase抽象类和IImsService接口,接着由芯片厂商实现ImsService。
ImsConfig、ImsUt、ImsCall等对象最终是依靠ImsService来创建的,
由此可见,其他三种通信方式都是依赖着ImsService的。

ImsManager—>ImsService—>Vendor RIL
这种通信方式主要用来通知modem turn on/off Ims。
使用场景就是在VoLTE、WFC和Advanced4GMode等功能被用户手动enable/disable时,就要响应地通知modem turn on/off Ims了。

ImsConfig

ImsManager—>ImsConfig—>Vendor RIL
ImsConfig主要就是提供接口给上层动态地去控制IMS功能的能力、参数等。
ImsConfig类中虽然只有7个方法,但是功能强大,特别是下面几个方法

public int getProvisionedValue();
public int setProvisionedValue();
public String getProvisionedStringValue();
public int setProvisionedStringValue();

这些方法为开发者打开了一扇大门!通向底层NV的大门!(不同芯片厂商可能有差异)比如,在UI界面上点击了打开WFC的按钮,就可以间接地修改到NV的某一项。
目前Android 7.0中支持的NV只有几十个,但是这并不能满足OEM所有的需求,所以有时候还需扩展这个接口。

还有就是,如果要开发IMS接口的话,建议也是加在这里,其他通道都不太合适。

ImsCall

ImsManager—>ImsCall—>ImsCallSession—>Vendor RIL
这个就很明显了,这条通道是专门处理IMS Call相关事务的,创建ImsCall的方式有两种:
1. IMS MO Call时,通过ImsManager.makeCall()来创建;
2. IMS MT Call时,通过ImsManager.takeCall()来创建。
在ImsCall中,每个对Call操作的方法(accept/reject/hold/resume/merge等等)都会有对应的回调方法:

    /**
* @see Listener#onCallResumed, Listener#onCallResumeFailed
*/
public void resume(){
......
}

如果resume成功则通过onCallResumed()方法通知上层,如果resume失败则通过onCallResumeFailed()方法通知上层,一般的流程如下:

ImsUt

ImsManager—>ImsUt—>Vendor RIL
这条通道是专门提供向上提供设置补充业务接口的,如呼叫转移、呼叫限制、呼叫等待、outgoing Caller Id display等等。

最后,更多关于IMS的内容,请查阅如下协议文档:
- GSMA IR.92 : features for voice and sms profile
- GSMA IR.94 : video calling feature
- 3GPP TS 24.229 : IMS call control (SIP and SDP)
- 3GPP TS 26.114 : IMS media handling and interaction
- 3GPP TS 26.111 : Codec for CS multimedia telephony service (H.324)
- 3GPP TS 24.623 : XCAP over the Ut interface for manipulating supplementary services

————————————————
版权声明:本文为CSDN博主「linyongan」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/linyongan/article/details/53350493

Android 7.0 IMS框架详解的更多相关文章

  1. android 6.0 权限设置详解

    从Android 6.0版本开始,在安装应用时,该应用无法取得任何权限. 相反,在使用应用的过程中,若某个功能需要获取某个权限,系统会弹出一个对话框,显式地由用户决定是否将该权限赋予应用. 只有得到了 ...

  2. [转]Android 5.0——Material Design详解(动画篇)

    Material Design:Google推出的一个全新的设计语言,它的特点就是拟物扁平化. Material Design包含了很多内容,今天跟大家分享一下Material新增的动画: 在Andr ...

  3. OAuth 2.0授权框架详解

    目录 简介 OAuth的构成 refresh Token Authorization Code模式 隐式授权 Resource Owner 授权密码认证 Client 认证授权 github的OAut ...

  4. Android 常用的ORM框架详解

    1. OrmLite OrmLite 不是 Android 平台专用的ORM框架,它是Java ORM.支持JDBC连接,Spring以及Android平台.语法中广泛使用了注解(Annotation ...

  5. Android EventBus 3.0 实例使用详解

    EventBus的使用和原理在网上有很多的博客了,其中泓洋大哥和启舰写的非常非常棒,我也是跟着他们的博客学会的EventBus,因为是第一次接触并使用EventBus,所以我写的更多是如何使用,源码解 ...

  6. Spark2.1.0——内置Web框架详解

    Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...

  7. Spark2.1.0——内置RPC框架详解

    Spark2.1.0——内置RPC框架详解 在Spark中很多地方都涉及网络通信,比如Spark各个组件间的消息互通.用户文件与Jar包的上传.节点间的Shuffle过程.Block数据的复制与备份等 ...

  8. Android图片缓存之Bitmap详解

    前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...

  9. Android 之窗口小部件详解--App Widget

    Android 之窗口小部件详解--App Widget  版本号 说明 作者 日期  1.0  添加App Widge介绍和示例  Sky Wang 2013/06/27        1 App ...

随机推荐

  1. RRT路径规划算法(matlab实现)

    基于快速扩展随机树(RRT / rapidly exploring random tree)的路径规划算法,通过对状态空间中的采样点进行碰撞检测,避免了对空间的建模,能够有效地解决高维空间和复杂约束的 ...

  2. NX二次开发-基于MFC界面对话框与NX交互的开发

    打开VS2013 点击新建,选择MFC DLL 点击确定 点下一步 什么都不改,直接点完成 进来之后先编译一下,看是否编译成功 打开项目属性,更改这几处 $(UGII_BASE_DIR)\ugopen ...

  3. js 读取本地文件(必须通过input控件才能实现) 及 下载文件

    js 操作 文件的实现原理: 1.js是不能直接操作(读写)文件的,html的  input[type="file"] 控件是可以读取文件数据(获取文件数据流)的.js可以获取这个 ...

  4. Spring Boot项目生成jar包,并在windows服务器中注册成服务,开机启动

    背景: 使用Spring Boot开发的Web项目,打包生成了一个jar包,希望能部署在Windows服务器中 尝试: 1.Spring Boot生成的jar包,可以直接用java -jar运行,但是 ...

  5. Cell的复用机制问题总结

    创建方式汇总,注册和不注册Cell注册的两种方式 1.tableView registerNib:(nullable UINib *) forCellReuseIdentifier:(nonnull ...

  6. CSS:CSS 盒子模型

    ylbtech-CSS:CSS 盒子模型 1.返回顶部 1. CSS 盒子模型 CSS 盒子模型(Box Model) 所有HTML元素可以看作盒子,在CSS中,"box model&quo ...

  7. jQuery 对文档的操作

    通过jquery方式实现页面各种节点的追加.修改.删除.复制等操作 节点追加 1 父子关系追加 /*************************************************** ...

  8. 9、TestNG介绍与安装

    介绍 TestNG是一个受JUnit和NUnit启发的测试框架,但引入了一些新功能,使其更加强大和易于使用,例如: 注释. 在任意大的线程池中运行你的测试,这些线程池有各种可用的策略(所有方法在他们自 ...

  9. netif_rx解析

    netif_rx函数是在网上收到数据包后,通过中断机制通知CPU而间接调用的中断处理例程. 首先,会将Packet传给netpoll框架,该框架用于在网络协议栈不可用的情况下,也能够提供给内核一个收发 ...

  10. 并发编程之CAS(二)

    更多Android架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从以下几个内容来阐述CAS: [CAS原理] [CAS带来的ABA问题] 一 ...