安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

蓝牙音乐播放状态和歌曲信息不更新

安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

安卓版本android-9 (P版本)

问题现象:歌曲信息和蓝牙音乐的播放状态不更新,蓝牙音乐界面感觉卡死(其实是界面信息不更新,音频数据正常)

歌曲信息和播放状态的更新都是通过avrcp协议的通知事件进行更新的,一般而言avrcp的通知事件只要TG端有变化就会通过changed事件告知CT,具体通知指令如下:
播放状态
安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

歌曲信息
安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

难道是对端手机异常不再主动通知changed事件了?-_- 带着这个怀疑赶紧分析了logcat,发现在某一次的通知TG端回复changed事件后,CT端没有注册新的通知事件到手机,导致后续的changed事件手机都没法通知到设备端。
安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

没有重新注册新的通知事件的原因是没有可用的事务标签号,Avrcp协议中对 Transaction Labels 定义如下:
安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

从协议可知 Transaction Labels 最多支持16条,可同时注册或者等待响应的事件应该限制为15条,而bluedroid中也有如上最多16条的限制,那为何还会资源不足呢?

#define MAX_TRANSACTIONS_PER_SESSION 16

分析代码 handle_avk_rc_metamsg_rsp() 函数中的逻辑,发现其中对于 AVRC_PDU_REGISTER_NOTIFICATION 的changed事件处理逻辑是先注册新的通知事件到TG,最后才会释放前一次使用的Transaction Label,这样必须得有一个可用的Transaction Label在资源池中监听才不会停止。

那在极端状态下(当前16条Transaction Label都在使用中),某一个通知的changed事件回复,在注册新的通知事件时就会没有Transaction Label可用,从而监听就突然停掉,相关信息再也不会更新。

解决方案
对于 AVRC_PDU_REGISTER_NOTIFICATION 事件在changed时先释放 Transaction Label,如此能保证 transaction资源池中至少有一个 ID 是可用的。感兴趣的同学欢迎私信留言一起讨论,共同学习,一起进步!

更多互联互通技术,欢迎关注微信公众号:Connectivity
安卓源码避坑指南10—蓝牙音乐播放状态和歌曲信息不更新

上一篇:FPGA之道(35)Verilog中的并行与串行语句


下一篇:Facebook再改信息流推送算法:强调"有信息价值"