文章目录
- 1. MO 显示 InCall UI 流程(基于 Android Q)
- 1.1 主要流程
- 1.2 需注意的点
- 2. MO 拨号流程
- 2.1 主要流程
- 2.2 需注意的点
1. MO 显示 InCall UI 流程(基于 Android Q)
1.1 主要流程
- 拨出电话从 DialpadFragment 的拨号按钮按下开始,直到调用到 TelecomManager 的 placeCall()方法进入到真正的流程入口
- TelecomManager 的服务实现 TelecomServiceImpl 将检查发起拨号的应用是否有拨号的权限,如果有则开始处理 拨号的 Intent
- 拨号 Intent 由 UserCallIntentProcessor 处理,最终调用到 CallIntentProcessor 进行进一步处理
- CallIntentProcessor 有两个流程分支,其中拉起 InCall UI 是直接进入 CallsManager 中调用 addCall 方法,并唤醒监听该消息的 listener
- InCallController 监听到 onCallAdded()消息,开始绑定 InCallService,最终流程进入到InCallServiceImpl 子类实现中
- InCallServiceImpl 调用 InCallPresenter 的 onCallAdded()方法
- InCallPresenter 通知 CallList 有call 被添加,则创建出 DialerCall 对象用于存储 Dialer 中的Call状态
- DialerCall 注册监听 telecomCall 的状态,并根据其变化更新自身,随后将变化反映到UI 上
- InCall UI 的显示通过 InCallPresenter 的 showInCall()方法实现
1.2 需注意的点
- InCallService 的绑定是容易出问题的点,如果绑定失败或者不匹配,就会出现电话拨出去有声音,但是不显示InCallUI 的问题
- InCallUI 界面的显示信息都存储在 DialerCall 对象中,该对象又是根据 telecomCall 来更新的,故如InCallUI显示不对可对此进行排查
- 总的来说,显示 InCall UI 流程主要分为 3 部分:【1】处理Call Intent ;【2】InCallController 绑定 InCallService;【3】InCallService 通过 InCallPresenter 拉起UI
2. MO 拨号流程
2.1 主要流程
- 最初的流程与 拉起 InCallUI类似,先处理 Call Inetnt, 然后CallIntentProcessor 的另一支流程会创建 NewOutgoingCallIntentBrocaster
- 通过 NewOutgoingCallIntentBroadcaster 对象进行紧急电话的评估,然后进入NewOutgoingCallIntentBroadcaster 处理Call 的流程。
- NewOutgoingCallIntentBroadcaster 中会根据电话是否是紧急拨号决定是否简化拨号流程。 正常拨号是通过CallsManager 的 placeOutgoingCall 方法,通过 Call 对象方法 startCreateConnection 来创建连接
- 创建连接需通过 CreateConnectionProcessor来进行,首先选择PhoneAccount,接下来主要分为了两步:【1】创建ConnectionService,【2】通过ConnectionService创建 Connection。
具体步骤为使用 ConnectionServiceWrapper 来绑定 ConnectionService, 使用其子类 TelephonyConnectionService 来实现实际创建 Connection的 逻辑。Connection 也有许多子实现,首先确定拨打电话需要创建 TelephonyConnection,之后根据Phone 的type 创建出 GsmConnection - Connection 创建完毕, TelephonyConnectionService 调用 placeOutgoingConnection 方法,通过Phone 对象调用 dial()方法进行拨号
- 在GsmCdmaPhone 对象的拨号方法中会判断 ImsPhone对象是否存在,并根据相关配置决定是否要用ImsPhone对象来进行拨号
- 之后就是 GsmCdmaPhoneCallTracker / ImsPhoneCallTracker 对象与底层交互的流程。【1】如果是使用 GsmCdmaPhone对象拨号,GsmCdmaPhoneCallTracker中会与 RILJ 交互;【2】如果是使用ImsPhone对象拨号,则需要通过 ImsManager 调用到各个平台自行实现的 Ims.apk来完成拨号流程
2.2 需注意的点
- Android Q 上紧急电话的流程有较大改变,添加了专门的EmergencyNumberTracker 类来处理紧急电话。列表主要由底层上报,并且判断时会遍历两个Phone对象的列表,如果号码匹配了任何一张列表都认为其属于紧急电话。另外 Android 原生代码在此有个很辣眼睛的逻辑,那就是对 Phone 对象所拥有的 EmergencyNumberTracker 对象进行了两次判空操作,不知道 Q 正式 release时是否会fix
- 总结起来,MO 的拨号流程主要分为 3 部分:【1】处理Call Intent ;【2】通过 ConnectionServiceWrapper绑定 ConnectionService,再创建出拨号所需的Connection;【3】通过Phone对象发起拨号请求