BluetoothHeadsetClient rejectCall用于拒接电话,代码如下:
//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothHeadsetClient.java
public final class BluetoothHeadsetClient implements BluetoothProfile, AutoCloseable {
public boolean rejectCall(BluetoothDevice device) {
if (DBG) log("rejectCall()");
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.rejectCall(device, 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的rejectCall,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;
@Override
public boolean rejectCall(BluetoothDevice device) {
HeadsetClientStateMachine sm = getStateMachine(device); //取得状态机
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
&& connectionState != BluetoothProfile.STATE_CONNECTING) {
return false;
}
Message msg = sm.obtainMessage(HeadsetClientStateMachine.REJECT_CALL);
sm.sendMessage(msg); //发送REJECT_CALL消息
return true;
}
}
发送REJECT_CALL消息,发送的消息会在HeadsetClientStateMachine内部类Connected的processMessage中处理:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
class Connected extends State {
@Override
public synchronized boolean processMessage(Message message) {
case REJECT_CALL:
rejectCall();
break;
}
}
}
}
调用rejectCall方法:
//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
private final NativeInterface mNativeInterface;
private void rejectCall() {
int action;
logD("rejectCall");
HfpClientCall c = getCall(HfpClientCall.CALL_STATE_INCOMING,
HfpClientCall.CALL_STATE_WAITING,
HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD,
HfpClientCall.CALL_STATE_HELD); //获取HfpClientCall对象
if (c == null) {
logD("No call to reject, returning.");
return;
}
switch (c.getState()) { //判断通话状态
case HfpClientCall.CALL_STATE_INCOMING:
action = HeadsetClientHalConstants.CALL_ACTION_CHUP;
break;
case HfpClientCall.CALL_STATE_WAITING:
case HfpClientCall.CALL_STATE_HELD:
action = HeadsetClientHalConstants.CALL_ACTION_CHLD_0;
break;
case HfpClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
action = HeadsetClientHalConstants.CALL_ACTION_BTRH_2;
break;
case HfpClientCall.CALL_STATE_ACTIVE:
case HfpClientCall.CALL_STATE_DIALING:
case HfpClientCall.CALL_STATE_ALERTING:
default:
return;
}
if (mNativeInterface.handleCallAction(mCurrentDevice, action, 0)) {
logD("Reject call action " + action);
addQueuedAction(REJECT_CALL, action); //添加REJECT_CALL到Action队列
} else {
Log.e(TAG, "ERROR: Couldn't reject a call, action:" + action);
}
}
}
调用NativeInterface的handleCallAction方法:
//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);
}
在之后就是蓝牙协议栈相关内容,在这里就不再分析了。