Android13 BluetoothHeadsetClient terminateCall流程分析

BluetoothHeadsetClient terminateCall用于挂断电话,代码如下:

//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothHeadsetClient.java
public final class BluetoothHeadsetClient implements BluetoothProfile, AutoCloseable {
    public boolean terminateCall(BluetoothDevice device, BluetoothHeadsetClientCall call) {
        if (DBG) log("terminateCall()");
        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.terminateCall(device, call, 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的terminateCall,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 terminateCall(BluetoothDevice device, UUID uuid) {
        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.TERMINATE_CALL);
        msg.obj = uuid;
        sm.sendMessage(msg);  //发送TERMINATE_CALL消息
        return true;
    }
}

发送TERMINATE_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 TERMINATE_CALL:
                    terminateCall();
                    break;
            }
        }
    }
}

调用terminateCall方法:

//packages/modules/Bluetooth/android/app/srv/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
public class HeadsetClientStateMachine extends StateMachine {
    private final NativeInterface mNativeInterface;
    private void terminateCall() {
        logD("terminateCall");


        int action = HeadsetClientHalConstants.CALL_ACTION_CHUP;


        HfpClientCall c = getCall(HfpClientCall.CALL_STATE_DIALING,
                HfpClientCall.CALL_STATE_ALERTING,
                HfpClientCall.CALL_STATE_ACTIVE); //获取HfpClientCall对象
        if (c == null) {
            // If the call being terminated is currently held, switch the action to CHLD_0
            c = getCall(HfpClientCall.CALL_STATE_HELD);
            action = HeadsetClientHalConstants.CALL_ACTION_CHLD_0;
        }
        if (c != null) {
            if (mNativeInterface.handleCallAction(mCurrentDevice, action, 0)) {
                addQueuedAction(TERMINATE_CALL, action); //添加REJECT_CALL到Action队列
            } else {
                Log.e(TAG, "ERROR: Couldn't terminate outgoing call");
            }
        }
    }
}

调用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);
}

在之后就是蓝牙协议栈相关内容,在这里就不再分析了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值