藍芽之十二-HFP app層
在android6中,HFP的app層程式碼位於:
/packages/apps/Bluetooth/src/com/android/bluetooth/hfpclient
配置使能程式碼位於
<values/config.xml>
<bool name="profile_supported_hs_hfp">true</bool>
<bool name="profile_supported_hfpclient">true</bool>
如上,配置了hs和hfpclinent使能,由於程式碼會呼叫層次結構比較深,這裡以廣度優先法分析HFP功能。
首先和HFP client息息相關的有三個檔案。
HeadsetClientHalConstants.java
HeadsetClientService.java
HeadsetClientStateMachine.java
HeadsetClientHalConstants.java
這個檔案的命名就顯示其和HAL層是有關係的,裡面的常量定義是和HAL層一致的。
final public class HeadsetClientHalConstants {
// 如果這裡的定義有變化,需要和HAL bt_hf_client.h保持一致
// 0~4和bt_hf_client.h檔案裡定義的列舉型別是一致的,用於表示連線的斷開,正在連線,連線成功,SLC(Service Level Connection)連線,和正在斷開連線
final static int CONNECTION_STATE_DISCONNECTED = 0;
final static int CONNECTION_STATE_CONNECTING = 1;
final static int CONNECTION_STATE_CONNECTED = 2;
final static int CONNECTION_STATE_SLC_CONNECTED = 3;
final static int CONNECTION_STATE_DISCONNECTING = 4;
// 和bt_hf_client.h檔案 bthf_client_audio_state_t 定義的列舉保持一致,用於指示audio狀態
final static int AUDIO_STATE_DISCONNECTED = 0;
final static int AUDIO_STATE_CONNECTING = 1;
final static int AUDIO_STATE_CONNECTED = 2;
final static int AUDIO_STATE_CONNECTED_MSBC = 3;
// 和 bt_hf_client.h的bthf_client_vr_state_t定義的列舉型別一致,VR是voice Recognition的縮寫。
final static int VR_STATE_STOPPED = 0;
final static int VR_STATE_STARTED = 1;
//bt_hf_client.h定義的bthf_client_volume_type_t列舉音量調節物件,speaker還是mic。
final static int VOLUME_TYPE_SPK = 0;
final static int VOLUME_TYPE_MIC = 1;
// match up with bthf_client_network_state_t enum of bt_hf_client.h
final static int NETWORK_STATE_NOT_AVAILABLE = 0;
final static int NETWORK_STATE_AVAILABLE = 1;
// match up with bthf_client_service_type_t enum of bt_hf_client.h
final static int SERVICE_TYPE_HOME = 0;
final static int SERVICE_TYPE_ROAMING = 1;
// match up with bthf_client_call_state_t enum of bt_hf_client.h,RESP是response的縮寫
final static int CALL_STATE_ACTIVE = 0;
final static int CALL_STATE_HELD = 1;
final static int CALL_STATE_DIALING = 2;
final static int CALL_STATE_ALERTING = 3;
final static int CALL_STATE_INCOMING = 4;
final static int CALL_STATE_WAITING = 5;
final static int CALL_STATE_HELD_BY_RESP_HOLD = 6;
// match up with bthf_client_call_t enum of bt_hf_client.h
final static int CALL_NO_CALLS_IN_PROGRESS = 0;
final static int CALL_CALLS_IN_PROGRESS = 1;
// match up with bthf_client_callsetup_t enum of bt_hf_client.h
final static int CALLSETUP_NONE = 0;
final static int CALLSETUP_INCOMING = 1;
final static int CALLSETUP_OUTGOING = 2;
final static int CALLSETUP_ALERTING = 3;
// match up with bthf_client_callheld_t enum of bt_hf_client.h
final static int CALLHELD_NONE = 0;
final static int CALLHELD_HOLD_AND_ACTIVE = 1;
final static int CALLHELD_HOLD = 2;
// match up with btrh_client_resp_and_hold_t of bt_hf_client.h
final static int RESP_AND_HOLD_HELD = 0;
final static int RESP_AND_HOLD_ACCEPT = 1;
final static int RESP_AND_HOLD_REJECT = 2;
// match up with bthf_client_call_direction_t enum of bt_hf_client.h
final static int CALL_DIRECTION_OUTGOING = 0;
final static int CALL_DIRECTION_INCOMING = 1;
// match up with bthf_client_call_mpty_type_t enum of bt_hf_client.h,SINGLE單電話, MULTI多方電話
final static int CALL_MPTY_TYPE_SINGLE = 0;
final static int CALL_MPTY_TYPE_MULTI = 1;
// match up with bthf_client_cmd_complete_t enum of bt_hf_client.h,命令完成應答
final static int CMD_COMPLETE_OK = 0;
final static int CMD_COMPLETE_ERROR = 1;
final static int CMD_COMPLETE_ERROR_NO_CARRIER = 2;
final static int CMD_COMPLETE_ERROR_BUSY = 3;
final static int CMD_COMPLETE_ERROR_NO_ANSWER = 4;
final static int CMD_COMPLETE_ERROR_DELAYED = 5;
final static int CMD_COMPLETE_ERROR_BLACKLISTED = 6;
final static int CMD_COMPLETE_ERROR_CME = 7;
// match up with bthf_client_call_action_t enum of bt_hf_client.h,呼叫動作
final static int CALL_ACTION_CHLD_0 = 0;
final static int CALL_ACTION_CHLD_1 = 1;
final static int CALL_ACTION_CHLD_2 = 2;
final static int CALL_ACTION_CHLD_3 = 3;
final static int CALL_ACTION_CHLD_4 = 4;
final static int CALL_ACTION_CHLD_1x = 5;
final static int CALL_ACTION_CHLD_2x = 6;
final static int CALL_ACTION_ATA = 7;
final static int CALL_ACTION_CHUP = 8;
final static int CALL_ACTION_BTRH_0 = 9;
final static int CALL_ACTION_BTRH_1 = 10;
final static int CALL_ACTION_BTRH_2 = 11;
// match up with bthf_client_subscriber_service_type_t enum of
// bt_hf_client.h
final static int SUBSCRIBER_SERVICE_TYPE_UNKNOWN = 0;
final static int SUBSCRIBER_SERVICE_TYPE_VOICE = 1;
final static int SUBSCRIBER_SERVICE_TYPE_FAX = 2;
// match up with bthf_client_in_band_ring_state_t enum in bt_hf_client.h,電話鈴聲同傳
final static int IN_BAND_RING_NOT_PROVIDED = 0;
final static int IN_BAND_RING_PROVIDED = 1;
// AG(Audio Gate) features masks,
// match up with masks in bt_hf_client.h
// Three-way calling
final static int PEER_FEAT_3WAY = 0x00000001;
// Echo cancellation and/or noise reduction
final static int PEER_FEAT_ECNR = 0x00000002;
// Voice recognition
final static int PEER_FEAT_VREC = 0x00000004;
// In-band ring tone
final static int PEER_FEAT_INBAND = 0x00000008;
// Attach a phone number to a voice tag
final static int PEER_FEAT_VTAG = 0x00000010;
// Ability to reject incoming call
final static int PEER_FEAT_REJECT = 0x00000020;
// Enhanced Call Status
final static int PEER_FEAT_ECS = 0x00000040;
// Enhanced Call Control
final static int PEER_FEAT_ECC = 0x00000080;
// Extended error codes
final static int PEER_FEAT_EXTERR = 0x00000100;
// Codec Negotiation
final static int PEER_FEAT_CODEC = 0x00000200;
// AG's 3WC features masks
// match up with masks in bt_hf_client.h
// 0 Release waiting call or held calls
final static int CHLD_FEAT_REL = 0x00000001;
// 1 Release active calls and accept other (waiting or held) cal
final static int CHLD_FEAT_REL_ACC = 0x00000002;
// 1x Release specified active call only
final static int CHLD_FEAT_REL_X = 0x00000004;
// 2 Active calls on hold and accept other (waiting or held) call
final static int CHLD_FEAT_HOLD_ACC = 0x00000008;
// 2x Request private mode with specified call (put the rest on hold)
final static int CHLD_FEAT_PRIV_X = 0x00000010;
// 3 Add held call to multiparty */
final static int CHLD_FEAT_MERGE = 0x00000020;
// 4 Connect two calls and leave (disconnect from) multiparty */
final static int CHLD_FEAT_MERGE_DETACH = 0x00000040;
// AT Commands
// These Commands values must match with Constants defined in
// tBTA_HF_CLIENT_AT_CMD_TYPE in bta_hf_client_api.h
// used for sending vendor specific AT cmds to AG.
final static int HANDSFREECLIENT_AT_CMD_NREC = 15;
// Flag to check for local NREC support
final static boolean HANDSFREECLIENT_NREC_SUPPORTED = true;
}
HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
//狀態機,多例
private HeadsetClientStateMachine mStateMachine;
//Headset client服務端,單例,可以有多個HeadsetClient代理
private static HeadsetClientService sHeadsetClientService;
@Override,//代理的binder
public IProfileServiceBinder initBinder() {
return new BluetoothHeadsetClientBinder(this);
}
@Override
protected boolean start() {
mStateMachine = HeadsetClientStateMachine.make(this);//建立狀態機
IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
try {
//註冊廣播時間的過濾器和行為
registerReceiver(mBroadcastReceiver, filter);
} catch (Exception e) {
Log.w(TAG, "Unable to register broadcat receiver", e);
}
//啟動服務時,service存在檢查
setHeadsetClientService(this);
return true;
}
//broadcastReceiver類建立,該類向HeadsetClientStateMachine傳送音量設定訊息
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
if (streamType == AudioManager.STREAM_BLUETOOTH_SCO) {
int streamValue = intent
.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
int streamPrevValue = intent.getIntExtra(
AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
if (streamValue != -1 && streamValue != streamPrevValue) {
mStateMachine.sendMessage(mStateMachine.obtainMessage(
HeadsetClientStateMachine.SET_SPEAKER_VOLUME, streamValue, 0));
}
}
}
}
};
//frameworks/base/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl定義的client可以使用的介面實現。這些介面就是呼叫該service實現該方法的。
private static class BluetoothHeadsetClientBinder extends IBluetoothHeadsetClient.Stub
implements IProfileServiceBinder {
private HeadsetClientService mService;
...
}
//傳送訊息給state machine。實現連線功能
public boolean connect(BluetoothDevice device) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
return false;
}
int connectionState = mStateMachine.getConnectionState(device);
if (connectionState == BluetoothProfile.STATE_CONNECTED ||
connectionState == BluetoothProfile.STATE_CONNECTING) {
return false;
}
mStateMachine.sendMessage(HeadsetClientStateMachine.CONNECT, device);
return true;
}
總結一下,該檔案實現了aidl檔案的方法,這些方法包括連線,連線音訊,撥打/接聽/拒接等,這些方法的呼叫是通過JNI的。這些方法的實現通過傳送訊息給狀態機來完成。
HeadsetClientStateMachine.java
final class HeadsetClientStateMachine extends StateMachine {
//定義了四個狀態機,分別是未連線,正在連線/連線成功和音訊開啟四個狀態。
private final Disconnected mDisconnected;
private final Connecting mConnecting;
private final Connected mConnected;
private final AudioOn mAudioOn;
//塊靜態方法
static {
classInitNative();
}
相關文章
- 藍芽HFP 藍芽電話剖析(二) --- AT command集合藍芽
- 藍芽 電話 HFP 剖析(一) --- 概述藍芽
- 藍芽電話 HFP 剖析(三) --- flow解析藍芽
- 藍芽之九-AT命令藍芽
- 手機藍芽硬體APP公司分析藍芽自動重連機制藍芽APP
- 小程式之藍芽的使用藍芽
- 藍芽藍芽
- Android藍芽使用詳解(普通藍芽)Android藍芽
- android藍芽hal層程式碼跟蹤記錄Android藍芽
- 藍芽模組藍芽模組
- iOS 藍芽iOS藍芽
- ios 藍芽iOS藍芽
- Android藍芽那點事——深入瞭解藍芽BlE藍芽 《總結篇》Android藍芽
- iOS藍芽開發 Bluetooth藍芽CoreBluetooth 藍芽中心裝置的實現 藍芽外設的實現 有DemoiOS藍芽
- 安卓微信小程式開發之“藍芽”安卓微信小程式藍芽
- Android藍芽協議-藍芽掃描 startDiscoveryAndroid藍芽協議
- java+藍芽Java藍芽
- iOSBluetooth(藍芽)iOS藍芽
- 藍芽4.0 BLE藍芽
- MASA MAUI Plugin 安卓藍芽低功耗(一)藍芽掃描UIPlugin安卓藍芽
- MASA MAUI Plugin IOS藍芽低功耗(三)藍芽掃描UIPluginiOS藍芽
- 熊晨灃藍芽實戰--小程式藍芽連線2.0藍芽
- Android學習筆記之藍芽通訊...Android筆記藍芽
- 智慧裝置端與 APP 之間如何實現自動化測試 (藍芽 4.0)APP藍芽
- iOS藍芽開發iOS藍芽
- 藍芽工作流程藍芽
- 低功耗藍芽(5)藍芽
- 低功耗藍芽(2)藍芽
- 低功耗藍芽(3)藍芽
- 藍芽學習1藍芽
- BLE低功耗藍芽藍芽
- 藍芽耳機怎麼恢復中文模式 藍芽耳機調不了中文藍芽模式
- 藍芽解鎖AutoLock 1.0.2 Mac中文版 (藍芽WiFi解鎖工具)藍芽MacWiFi
- 電腦藍芽怎麼連線 電腦連線藍芽的方法藍芽
- 藍芽共享網路怎麼用 win10藍芽共享網路藍芽Win10
- Mac藍芽連線有問題該如何?教你重置Mac藍芽模組Mac藍芽模組
- 藍芽耳機怎麼按都不亮了 藍芽耳機長按無反應藍芽
- BLE藍芽那些事—深入瞭解Android藍芽Bluetooth基礎篇藍芽Android