安卓源碼避坑指南2—HF側撥打藍牙電話的ID號一直是 -1

安卓源碼避坑指南2—撥打藍牙電話的ID號一直是 -1

又到了喜聞樂見的環節——安卓源碼避坑指南,同事使用android-9源碼全編了個系統鏡像,安裝完成後在HF側主動撥打一通藍牙電話後發現電話的ID號一直爲-1,AT命令中的“+CLCC”中的idx參數協議中明確規定是從1開始計數的,表示當前的藍牙電話是第幾路電話。現在應用層卻收到一個第-1路的藍牙電話,這就很莫名其妙了,那本篇文章我們就來扒一扒這個問題吧。
在這裏插入圖片描述

環境:Android-P系統

操作

  1. 車載藍牙連接手機藍牙成功
  2. 通過車載端的藍牙電話應用主動撥打電話(以 10086 舉例)
  3. 藍牙電話應用層內監聽如下截圖的電話改變廣播從而來切換電話狀態顯示:
    在這裏插入圖片描述

現象:藍牙電話應用接收到廣播後解析出廣播中的BluetoothHeadsetClientCall,通過接口getId()獲取當前電話的ID號都是-1,log打印見下圖:
在這裏插入圖片描述

由於藍牙電話改變的廣播是由藍牙服務對外進行廣播的,所以藍牙電話的ID號賦值爲-1應該是在藍牙服務層進行操作的。話不多說,先來簡單瞭解下這塊邏輯的時序圖:
在這裏插入圖片描述

通過時序圖可以看到藍牙電話的處理大部分是在HFP-Client狀態機中,上圖中紅色字體標註的兩個變量就是本問題的根因所在。

  • mCalls:當前存在的所有藍牙電話

  • mCallsUpdate:本次AT+CLCC命令後需要更新信息的藍牙電話

追溯安卓源碼,發現第一次出現ID爲-1是在HeadsetClientService.dial()方法裏,該方法構造出一個新值BluetoothHeadsetClientCall,表示當前撥打的藍牙電話,其中的ID號使用的就是HeadsetClientStateMachine中的常量值HF_ORIGINATED_CALL_ID = -1,並將這個call隨着DIAL_NUMBER 消息一起下發到狀態機中,所以下發撥打電話指令後mCalls中保存的call的id爲-1。

mCallsUpdate中保存的都是從藍牙協議棧上報的電話信息,從HCI可以明顯發現,上報的電話的ID號都是1(當前只有這一個 10086
處於通話中)
在這裏插入圖片描述

那這問題應該是出在queryCallsDone()中,更新電話狀態時安卓源碼開發人員沒有考慮到這個情況?

繼續查看該部分的源碼,我的天,源碼註釋裏已經考慮到這種情況了,那怎麼廣播出來的還是-1的ID號,一臉懵逼中…
在這裏插入圖片描述

繼續分析源碼更新的步驟,終於被我一雙慧眼看出其中的貓膩,哈哈
在這裏插入圖片描述

到這裏我就無恥地笑了,總算被我找到根因,從始至終call裏的ID值都沒有改變,這樣不管後面的電話狀態怎麼變,ID號都爲-1。

原因找到了,那我們就想想解決方案吧。我這邊提供一種方案如下截圖,嘻嘻
在這裏插入圖片描述

重新單編藍牙服務模塊Bluetooth.apk或者全編system.img,驗證後問題得到解決。感興趣的小夥伴歡迎私信留言其他好的解決方案,我們一起討論。

更多互聯互通技術,歡迎關注微信公衆號:Connectivity
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章