一递沪、telecom進(jìn)程和bluetooth進(jìn)程的交互方方式
1. telecom進(jìn)程主動(dòng)控制藍(lán)牙的操作是通過(guò)跨進(jìn)程調(diào)用bluetooth進(jìn)程中HeadService的接口家破。
2. 藍(lán)牙狀態(tài)變更是通過(guò)廣播通知telecom進(jìn)程那婉。
如下圖:
具體細(xì)節(jié)如下:
telecom進(jìn)程在創(chuàng)建時(shí),TelecomService會(huì)創(chuàng)建BluetoothDeviceManager類來(lái)負(fù)責(zé)所有和bluetooth進(jìn)程有關(guān)的操作:BluetoothAdapter的代理類BluetoothAdapterProxy創(chuàng)建BluetoothHeadset铡恕,負(fù)責(zé)跨進(jìn)程調(diào)用HeadsetService中的接口睦尽,然后把它返回給一個(gè)代理類BluetoothHeadsetProxy宇攻,所有和藍(lán)牙的有關(guān)操作都直接通過(guò)這個(gè)代理類處理尖淘。同時(shí),TelecomService會(huì)創(chuàng)建一個(gè)專門(mén)用來(lái)接收藍(lán)牙廣播的類BluetoothStateReceiver著觉,收到廣播后通過(guò)BluetoothRouteManager來(lái)通知管理通話audio route的CallAudioRouteManager村生,然后通知界面更新。用戶在通話界面切換聲音模式時(shí)也是通過(guò)CallAudioRouteManager通知BluetoothRouteManager然后調(diào)用用BluetoothHeadset的接口來(lái)處理饼丘。BluetoothRouteManager是通話audio route和藍(lán)牙相關(guān)信息的中轉(zhuǎn)站趁桃。
二、Telecom接收的藍(lán)牙廣播
BluetoothHeadset.ACTIVE_ACTIVE_DEVICE_CHANGED
這個(gè)廣播是在藍(lán)牙打開(kāi)肄鸽,有藍(lán)牙設(shè)備連接或者斷開(kāi)時(shí)發(fā)送卫病。收到這個(gè)廣播后,telecom會(huì)根據(jù)當(dāng)前device的連接狀態(tài)來(lái)判斷是否要切換為bluetooth route典徘。如下圖:
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED
這個(gè)廣播是藍(lán)牙開(kāi)關(guān)打開(kāi)或關(guān)閉時(shí)發(fā)送蟀苛。收到這個(gè)廣播后telecom會(huì)更新當(dāng)前支持的audio routes。如圖:
BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
這個(gè)廣播是HFP連接或斷開(kāi)時(shí)發(fā)送逮诲。如圖:
這個(gè)廣播不僅會(huì)讓telecom切換當(dāng)前audio route也是唯一一個(gè)會(huì)引起 BluetoothRouteManager切換bluetooth StateMachine切換狀態(tài)的廣播帜平。
三、BluetoothRouteManager StateMachine
先介紹一下StateMachine里面頻繁用到的一個(gè)專有名詞:HFP梅鹦。
HFP(Hands-free Profile):讓藍(lán)牙設(shè)備可以控制電話裆甩,如接聽(tīng)、掛斷帘瞭、拒接淑掌、語(yǔ)音音撥號(hào)等,拒接蝶念、語(yǔ)音撥號(hào)要視藍(lán)牙耳機(jī)及電話是否支持抛腕,是讓藍(lán)牙耳機(jī)進(jìn)入高保真通話的一種可設(shè)置模式。
再來(lái)看SM的構(gòu)成:
從圖中可以看出:
1. CONNECT_HFP只能切換到AudioConnectingState媒殉,要等到HFP_IS_ON才會(huì)把狀態(tài)切換成AudioConnectedState担敌。DISCONNECT_HFP一定會(huì)把狀態(tài)切換成AudioOffState,但HFP_LOST不一定廷蓉。CONNECT_HFP DISCONNECT_HFP是通話主動(dòng)發(fā)起的藍(lán)牙狀態(tài)連接或斷開(kāi)全封,而HFP_IS_ON HFP_LOST是藍(lán)牙上報(bào)的設(shè)備audio連接或斷開(kāi)。
2. 不同的藍(lán)牙設(shè)備分別有自己的AudioConnectingState和AudioConnectedState狀態(tài),但AudioOffState狀態(tài)卻不分設(shè)備桃犬。這就會(huì)引起一個(gè)問(wèn)題:
例如:當(dāng)一臺(tái)手機(jī)連接兩個(gè)藍(lán)牙耳機(jī)A和B,目前通話正在使用A刹悴,用戶在藍(lán)牙設(shè)置界面選擇切換成B。此時(shí),藍(lán)牙會(huì)先斷開(kāi)A的audio連接然后再建立B的audio連接攒暇。于是通話會(huì)先收到A的HFP_LOST然后再收到B的HFP_IS_ON土匀,這里就會(huì)有一個(gè)time issue:當(dāng)AudioConnectedState收到HFP_LOST時(shí)B的audio沒(méi)有連接上,但進(jìn)入到AudioOffState前B的audio連接上了,此時(shí)在AudioOffState的enter中會(huì)斷開(kāi)B的連接,導(dǎo)致聲道切換成B失敗形用,而從聽(tīng)筒出聲就轧。
原因:A和B沒(méi)有自己的AudioOffState,導(dǎo)致?tīng)顟B(tài)混亂证杭。
解決方法:給接收HFP_LOST斷開(kāi)的設(shè)備建立它自己的AudioOffState。
四妒御、通話中用戶主動(dòng)切換藍(lán)牙聲道
耳機(jī)切換至藍(lán)牙
當(dāng)用戶主動(dòng)切換到藍(lán)牙聲道時(shí)解愤,CallAudioRouteStateMachine在切換到BluetoothRoute之前會(huì)先打開(kāi)藍(lán)牙,同時(shí)發(fā)送CONNECT_HFP消息,從AudioOffState切換到AudioConnectingState乎莉,這時(shí)會(huì)觸發(fā)一個(gè)timeout送讲,圖中沒(méi)有表示,具體可以去看代碼梦鉴。當(dāng)藍(lán)牙audio連接時(shí),會(huì)發(fā)送BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED的廣播李茫,收到這個(gè)廣播后會(huì)發(fā)送HFP_IS_ON的message給SM揭保,然后從AudioConnectingState切換到AudioConnectedState肥橙。進(jìn)入AudioConnectedState之后會(huì)通知CallAudioRouteStateMachine切換到BluetoothRoute。如下圖:
藍(lán)牙切換至耳機(jī)
進(jìn)入非BluetoothRoute時(shí)會(huì)把藍(lán)牙audio斷開(kāi)秸侣。如下圖:
五存筏、藍(lán)牙主動(dòng)上報(bào)狀態(tài)更新
通話中,連接藍(lán)牙設(shè)備
如上圖:收到Bluetooth.ACTION_CONNECTION_STATE_CHANGED CONNECTED時(shí)更新可用的audioroutes,收到Bluetooth.ACTION_AUDIO_STATE_CHANGED CONNECTED時(shí)更新statemachine到AudioConnectedState和ActiveBluetoothRoute味榛。
非通話中椭坚,連接藍(lán)牙設(shè)備
如上圖:收到Bluetooth.ACTION_CONNECTION_STATE_CHANGED CONNECTED時(shí)更新可用的audioroutes搏色,收到Bluetooth.ACTION_DEVICE_STATE_CHANGED CONNECTED時(shí)更新statemachine到QuiescentBluetoothRoute善茎。
當(dāng)撥號(hào)或來(lái)電時(shí)會(huì)請(qǐng)求藍(lán)牙audio連接,藍(lán)牙audio連接后再切換到active或ringing bluetooth route频轿。
藍(lán)牙設(shè)備連接時(shí)垂涯,插入耳機(jī)
如下圖,此時(shí)通話會(huì)默認(rèn)切換到耳機(jī)通道
原創(chuàng)內(nèi)容歡迎轉(zhuǎn)載航邢,但請(qǐng)注明出處耕赘,謝謝!