BluetoothHeadsetClient的acceptCall用于接听电话,流程图如下:
代码如下:
//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothHeadsetClient.java
public final class BluetoothHeadsetClient implements BluetoothProfile, AutoCloseable {
public boolean acceptCall(BluetoothDevice device, int flag) {
if (DBG) log("acceptCall()");
final IBluetoothHeadsetClient service = getService();
final boolean defaultValue = false;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get();
service.acceptCall(device, flag, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
}
}
return defaultValue;
}
}
调用IBluetoothHeadsetClient的acceptCall方法,IBluetoothHeadsetClient是一个接口由HeadsetClientService的内部类BluetoothHeadsetClientBinder实现:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
private static class BluetoothHeadsetClientBinder extends IBluetoothHeadsetClient.Stub
implements IProfileServiceBinder {
private HeadsetClientService mService;
public void acceptCall(BluetoothDevice device, int flag, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
HeadsetClientService service = getService(source);
boolean defaultValue = false;
if (service != null) {
defaultValue = service.acceptCall(device, flag);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
receiver.propagateException(e);
}
}
}
}
调用HeadsetClientService的acceptCall方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
public class HeadsetClientService extends ProfileService {
public boolean acceptCall(BluetoothDevice device, int flag) {
/* Phonecalls from a single device are supported, hang up any calls on the other phone */
synchronized (mStateMachineMap) {
for (Map.Entry<BluetoothDevice, HeadsetClientStateMachine> entry : mStateMachineMap
.entrySet()) {
if (entry.getValue() == null || entry.getKey().equals(device)) {
continue;
}
int connectionState = entry.getValue().getConnectionState(entry.getKey());
if (DBG) {
Log.d(TAG,
"Accepting a call on device " + device + ". Possibly disconnecting on "
+ entry.getValue());
}
if (connectionState == BluetoothProfile.STATE_CONNECTED) {
entry.getValue()
.obtainMessage(HeadsetClientStateMachine.TERMINATE_CALL)
.sendToTarget();
}
}
}
HeadsetClientStateMachine sm = getStateMachine(device); //取得HeadsetClientStateMachine 对象
if (sm == null) {
Log.e(TAG, "SM does not exist for device " + device);
return false;
}
int connectionState = sm.getConnectionState(device); //取得设备状态,如果不适连接状态返回失败
if (connectionState != BluetoothProfile.STATE_CONNECTED) {
return false;
}
Message msg = sm.obtainMessage(HeadsetClientStateMachine.ACCEPT_CALL);
msg.arg1 = flag;
sm.sendMessage(msg); //发送ACCEPT_CALL消息
return true;
}
}
发送ACCEPT_CALL消息,发送的消息会在HeadsetClientStateMachine内部类Connected的processMessage中处理:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
private final NativeInterface mNativeInterface;
class Connected extends State {
public synchronized boolean processMessage(Message message) {
switch (message.what) {
case ACCEPT_CALL:
acceptCall(message.arg1);
break;
}
}
}
}
调用acceptCall方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
private final NativeInterface mNativeInterface;
private void acceptCall(int flag) {
int action = -1;
logD("acceptCall: (" + flag + ")");
HfpClientCall c = getCall(HfpClientCall.CALL_STATE_INCOMING,
HfpClientCall.CALL_STATE_WAITING); //获取HfpClientCall 对象
if (c == null) {
c = getCall(HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD,
HfpClientCall.CALL_STATE_HELD);
if (c == null) {
return;
}
}
logD("Call to accept: " + c);
switch (c.getState()) { //判断当前状态
case HfpClientCall.CALL_STATE_INCOMING: //来电
if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
return;
}
action = HeadsetClientHalConstants.CALL_ACTION_ATA;
break;
case HfpClientCall.CALL_STATE_WAITING: //当已有活动呼叫时,等待呼叫状态。
if (callsInState(HfpClientCall.CALL_STATE_ACTIVE) == 0) {
// if no active calls present only plain accept is allowed
if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
return;
}
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
break;
}
// if active calls are present then we have the option to either terminate the
// existing call or hold the existing call. We hold the other call by default.
if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD
|| flag == BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
logD("Accepting call with accept and hold");
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
} else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE) {
logD("Accepting call with accept and reject");
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1;
} else {
Log.e(TAG, "Aceept call with invalid flag: " + flag);
return;
}
break;
case HfpClientCall.CALL_STATE_HELD: //呼叫处于保持状态
if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
} else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE) {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1;
} else if (getCall(HfpClientCall.CALL_STATE_ACTIVE) != null) {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_3;
} else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
} else {
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
}
break;
case HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: //已通过响应和保持保持的呼叫
action = HeadsetClientHalConstants.CALL_ACTION_BTRH_1;
break;
case HfpClientCall.CALL_STATE_ALERTING:
case HfpClientCall.CALL_STATE_ACTIVE:
case HfpClientCall.CALL_STATE_DIALING:
default:
return;
}
if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
// When unholding a call over Bluetooth make sure to route audio.
//通过蓝牙取消通话时,请确保路由音频。
routeHfpAudio(true);
}
if (mNativeInterface.handleCallAction(mCurrentDevice, action, 0)) { //调用NativeInterface的handleCallAction,处理Call活动
addQueuedAction(ACCEPT_CALL, action); //将ACCEPT_CALL加入队列
} else {
Log.e(TAG, "ERROR: Couldn't accept a call, action:" + action);
}
}
}
调用NativeInterface的handleCallAction,处理Call活动:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/NativeInterface.java
public class NativeInterface {
public boolean handleCallAction(BluetoothDevice device, int action, int index) {
return handleCallActionNative(getByteAddress(device), action, index);
}
}
调用handleCallActionNative方法,并返回处理结果,handleCallActionNative是Native方法,通过查表调用的是handleCallActionNative方法:
static bthf_client_interface_t* sBluetoothHfpClientInterface = NULL;
//packages/modules/Bluetooth/android/app/jni/com_android_bluetooth_hfpclient.cpp
static jboolean handleCallActionNative(JNIEnv* env, jobject object,
jbyteArray address, jint action,
jint index) {
std::shared_lock<std::shared_mutex> lock(interface_mutex);
if (!sBluetoothHfpClientInterface) return JNI_FALSE;
jbyte* addr = env->GetByteArrayElements(address, NULL);
if (!addr) {
jniThrowIOException(env, EINVAL);
return JNI_FALSE;
}
bt_status_t status = sBluetoothHfpClientInterface->handle_call_action(
(const RawAddress*)addr, (bthf_client_call_action_t)action, (int)index);
if (status != BT_STATUS_SUCCESS) {
ALOGE("Failed to enter private mode, status: %d", status);
}
env->ReleaseByteArrayElements(address, addr, 0);
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
调用bthf_client_interface_t的handle_call_action函数,bthf_client_interface_t是个结构体,在bt_hf_client.h中定义,在bt_hf_client.cc中实现:
//packages/modules/Bluetooth/system/btif/src/bt_hf_client.cc
static bt_status_t handle_call_action(const RawAddress* bd_addr,
bthf_client_call_action_t action,
int idx) {
btif_hf_client_cb_t* cb = btif_hf_client_get_cb_by_bda(*bd_addr);
if (cb == NULL || !is_connected(cb)) return BT_STATUS_FAIL;
CHECK_BTHF_CLIENT_SLC_CONNECTED(cb);
switch (action) {
case BTHF_CLIENT_CALL_ACTION_CHLD_0:
if (cb->chld_feat & BTA_HF_CLIENT_CHLD_REL) {
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_CHLD_1:
// CHLD 1 is mandatory for 3 way calling
if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_CHLD_2:
// CHLD 2 is mandatory for 3 way calling
if (cb->peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY) {
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_CHLD_3:
if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE) {
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_CHLD_4:
if (cb->chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH) {
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_CHLD_1x:
if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
if (idx < 1) {
return BT_STATUS_FAIL;
}
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_CHLD_2x:
if (cb->peer_feat & BTA_HF_CLIENT_PEER_ECC) {
if (idx < 1) {
return BT_STATUS_FAIL;
}
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL);
break;
}
return BT_STATUS_UNSUPPORTED;
case BTHF_CLIENT_CALL_ACTION_ATA:
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
break;
case BTHF_CLIENT_CALL_ACTION_CHUP:
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL);
break;
case BTHF_CLIENT_CALL_ACTION_BTRH_0:
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL);
break;
case BTHF_CLIENT_CALL_ACTION_BTRH_1:
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL);
break;
case BTHF_CLIENT_CALL_ACTION_BTRH_2:
BTA_HfClientSendAT(cb->handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL);
break;
default:
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
调用BTA_HfClientSendAT方法:
//packages/modules/Bluetooth/system/bta/hf_client/bta_hf_client_api.cc
void BTA_HfClientSendAT(uint16_t handle, tBTA_HF_CLIENT_AT_CMD_TYPE at,
uint32_t val1, uint32_t val2, const char* str) {
tBTA_HF_CLIENT_DATA_VAL* p_buf =
(tBTA_HF_CLIENT_DATA_VAL*)osi_malloc(sizeof(tBTA_HF_CLIENT_DATA_VAL));
p_buf->hdr.event = BTA_HF_CLIENT_SEND_AT_CMD_EVT;
p_buf->uint8_val = at;
p_buf->uint32_val1 = val1;
p_buf->uint32_val2 = val2;
if (str) {
strlcpy(p_buf->str, str, BTA_HF_CLIENT_NUMBER_LEN + 1);
p_buf->str[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
} else {
p_buf->str[0] = '\0';
}
p_buf->hdr.layer_specific = handle;
bta_sys_sendmsg(p_buf);
}
在之后就是蓝牙协议栈相关内容,在这里就不再分析了。