Android13 BluetoothHeadsetClient rejectCall流程分析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值