概述
以下内容基于android Q。
手表通话分蓝牙通话、esim卡通话。esim卡通话和手机通话一样,通过modem和运营商基站通信。蓝牙通话则是把手机上的通话信息和状态同步到手表上,然后把手表上的操作返回到手机上进行实际处理。
设计结构
蓝牙通话和esim卡通话的主要区别,在于手表上的通话状态来自蓝牙而不是modem。如图
蓝牙通话基本逻辑
其具体细节如下:
Bluetooth和Telecom交互方式
可以看到手机端的交互是通过IBluetoothHeadsetPhone/IBluetoothHeadset交互,而手表端的Bluetooth app实现了ConnectionService,通过IConnectionService/IConnectionServiceAdapter交互,其和普通sim卡通话时telecom和telephony通过ConnectionService交互的区别如下:
蓝牙通话 vs sim卡通话
蓝牙app实现了telecom/Connection用来和Telecom/Call交换数据。
MO
要通话,首先要有一个PhoneAccount,蓝牙通话也注册了专门属于它的PhoneAccount,如下:
注册蓝牙通话PhoneAccount
这个PhoneAccount对应的Component为HfpClientConnectionService,这样Telecom可以区分它是蓝牙通话还是sim卡通话。
手表端MO的基本流程如下:
手表MO
Dialer拨号到InCall界面显示流程和sim卡通话一致,不同的是手表端Telecom拨号请求是通过HfpClientConnectionService传给蓝牙Native再传给手机蓝牙,再通过手机modem拨出去。概述为
手表端MO流程
手机端收到MO命令的流程为:
手机端接收MO请求
通话状态更新
因为手表端的通话状态是从蓝牙Native获取的,那么它是怎么更新的呢?如下:
手机端通话状态更新到手表
其中最重要的是手表端queryCallsStart()到queryCallsDone(),这个流程类似sim卡通话RIL向modem发送GET_CURRENT_CALLS请求,如下:
手表端QUERY_CURRENT_CALLS
MT
手表端的来电状态更新和普通Call状态变更更新类似,由手机端的telecom把信息传给蓝牙app,然后通过蓝牙Native传到手表。如下:
手表端来电
蓝牙app最后通过TelecomManager#addNewIncomingCall()通知手表端的Telecom来电,而如果是手机端拨号,则是通过TelecomManager#addNewUnknownCall()通知。
当手表端接听后,手机端的流程如下:
手机端收到手表端的接听命令
三方通话
手表三方通话实现的很简单,蓝牙app从蓝牙Native拿到了两个不同Id的通话,创建两个HfpClientConnection,然后传给Telecom。如下:
手表端的三方通话
会议通话
手表的会议电话实现也很简单,当HfpClientConnectionService发现新更新的Connection是多方通话的参与者时构建一个HfpClientConference,它实现telecom/Conference,然后把它发送给Telecom。如下:
手表端蓝牙通话会议电话前后Call状态变更
其具体实现如下:
手表端的会议电话
Conference/Connection传到Telecom后,其实现和sim卡会议电话一样。
总结
蓝牙通话其实就是在手表端的Telecom交互从Telephony变成了Bluetooth。
原创内容欢迎转载,但请注明出处,谢谢!