在android6中,HFP的app层代码位于:
/packages/apps/Bluetooth/src/com/android/bluetooth/hfpclient
配置使能代码位于
<bool name="profile_supported_hs_hfp">truebool>
<bool name="profile_supported_hfpclient">truebool>
如上,配置了hs和hfpclinent使能,由于代码会调用层次结构比较深,这里以广度优先法分析HFP功能。
首先和HFP client息息相关的有三个文件。
HeadsetClientHalConstants.java
HeadsetClientService.java
HeadsetClientStateMachine.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;
}
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的。这些方法的实现通过发送消息给状态机来完成。
final class HeadsetClientStateMachine extends StateMachine {
//定义了四个状态机,分别是未连接,正在连接/连接成功和音频打开四个状态。
private final Disconnected mDisconnected;
private final Connecting mConnecting;
private final Connected mConnected;
private final AudioOn mAudioOn;
//块静态方法
static {
classInitNative();
}