Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adce7c4b authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 7076087 from 7ac734fe to sc-release

Change-Id: I65a981e52771bc0b5370f645290fa60cb5b4cc70
parents 5df2c313 7ac734fe
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ cc_library_shared {
        "android/bluetooth/IBluetoothCallback.aidl",
        "android/bluetooth/IBluetoothProfileServiceConnection.aidl",
        "android/bluetooth/IBluetoothHeadset.aidl",
        "android/bluetooth/IBluetoothHeadsetPhone.aidl",
        "android/bluetooth/IBluetoothHearingAid.aidl",
        "android/bluetooth/IBluetoothHidHost.aidl",
        "android/bluetooth/IBluetoothPan.aidl",
@@ -93,7 +92,6 @@ filegroup {
        "android/bluetooth/IBluetoothCallback.aidl",
        "android/bluetooth/IBluetoothProfileServiceConnection.aidl",
        "android/bluetooth/IBluetoothHeadset.aidl",
        "android/bluetooth/IBluetoothHeadsetPhone.aidl",
        "android/bluetooth/IBluetoothHearingAid.aidl",
        "android/bluetooth/IBluetoothHidHost.aidl",
        "android/bluetooth/IBluetoothLeAudio.aidl",
+0 −39
Original line number Diff line number Diff line
/*
 * Copyright 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

/**
 * API for Bluetooth Headset Phone Service in phone app
 *
 * {@hide}
 */
interface IBluetoothHeadsetPhone {
  // Internal functions, not be made public
  boolean answerCall();
  boolean hangupCall();
  boolean sendDtmf(int dtmf);
  boolean processChld(int chld);
  String getNetworkOperator();
  String getSubscriberNumber();
  boolean listCurrentCalls();
  boolean queryPhoneState();

  // Internal for phone app to call
  void updateBtHandsfreeAfterRadioTechnologyChange();
  void cdmaSwapSecondCallState();
  void cdmaSetSecondCallState(boolean state);
}
+59 −14
Original line number Diff line number Diff line
@@ -487,6 +487,12 @@ void bta_gattc_conn(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
    /* a pending service handle change indication */
    if (p_clcb->p_srcb->srvc_hdl_chg) {
      p_clcb->p_srcb->srvc_hdl_chg = false;

      /* set true to read database hash before service discovery */
      if (bta_gattc_is_robust_caching_enabled()) {
        p_clcb->p_srcb->srvc_hdl_db_hash = true;
      }

      /* start discovery */
      bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
    }
@@ -595,6 +601,8 @@ void bta_gattc_set_discover_st(tBTA_GATTC_SERV* p_srcb) {
    if (bta_gattc_cb.clcb[i].p_srcb == p_srcb) {
      bta_gattc_cb.clcb[i].status = GATT_SUCCESS;
      bta_gattc_cb.clcb[i].state = BTA_GATTC_DISCOVER_ST;
      bta_gattc_cb.clcb[i].request_during_discovery =
          BTA_GATTC_DISCOVER_REQ_NONE;
    }
  }
}
@@ -625,6 +633,20 @@ void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  }
}

void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb) {
  if (p_clcb->transport == BT_TRANSPORT_LE)
    L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, false);

  bta_gattc_init_cache(p_clcb->p_srcb);
  p_clcb->status = bta_gattc_discover_pri_service(
      p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
  if (p_clcb->status != GATT_SUCCESS) {
    LOG(ERROR) << "discovery on server failed";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
  } else
    p_clcb->disc_active = true;
}

/** Start a discovery on server */
void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
                              UNUSED_ATTR tBTA_GATTC_DATA* p_data) {
@@ -640,25 +662,24 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
    p_clcb->auto_update = BTA_GATTC_NO_SCHEDULE;

    if (p_clcb->p_srcb != NULL) {
      /* set all srcb related clcb into discovery ST */
      bta_gattc_set_discover_st(p_clcb->p_srcb);

      /* clear the service change mask */
      p_clcb->p_srcb->srvc_hdl_chg = false;
      p_clcb->p_srcb->update_count = 0;
      p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;

      if (p_clcb->transport == BT_TRANSPORT_LE)
        L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, false);

      /* set all srcb related clcb into discovery ST */
      bta_gattc_set_discover_st(p_clcb->p_srcb);
      /* read db hash if db hash characteristic exists */
      if (bta_gattc_is_robust_caching_enabled() &&
          p_clcb->p_srcb->srvc_hdl_db_hash && bta_gattc_read_db_hash(p_clcb)) {
        LOG(INFO) << __func__
                  << ": pending service discovery, read db hash first";
        p_clcb->p_srcb->srvc_hdl_db_hash = false;
        return;
      }

      bta_gattc_init_cache(p_clcb->p_srcb);
      p_clcb->status = bta_gattc_discover_pri_service(
          p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
      if (p_clcb->status != GATT_SUCCESS) {
        LOG(ERROR) << "discovery on server failed";
        bta_gattc_reset_discover_st(p_clcb->p_srcb, p_clcb->status);
      } else
        p_clcb->disc_active = true;
      bta_gattc_start_discover_internal(p_clcb);
    } else {
      LOG(ERROR) << "unknown device, can not start discovery";
    }
@@ -961,8 +982,26 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data) {
  else if (op == GATTC_OPTYPE_CONFIG)
    bta_gattc_cfg_mtu_cmpl(p_clcb, &p_data->op_cmpl);

  // If receive DATABASE_OUT_OF_SYNC error code, bta_gattc should start service
  // discovery immediately
  if (bta_gattc_is_robust_caching_enabled() &&
      p_data->op_cmpl.status == GATT_DATABASE_OUT_OF_SYNC) {
    LOG(INFO) << __func__ << ": DATABASE_OUT_OF_SYNC, re-discover service";
    p_clcb->auto_update = BTA_GATTC_REQ_WAITING;
    /* request read db hash first */
    p_clcb->p_srcb->srvc_hdl_db_hash = true;
    bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
    return;
  }

  if (p_clcb->auto_update == BTA_GATTC_DISC_WAITING) {
    p_clcb->auto_update = BTA_GATTC_REQ_WAITING;

    /* request read db hash first */
    if (bta_gattc_is_robust_caching_enabled()) {
      p_clcb->p_srcb->srvc_hdl_db_hash = true;
    }

    bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
  }
}
@@ -1160,7 +1199,13 @@ bool bta_gattc_process_srvc_chg_ind(uint16_t conn_id, tBTA_GATTC_RCB* p_clrcb,
    GATTC_SendHandleValueConfirm(conn_id, p_notify->cid);

    /* if connection available, refresh cache by doing discovery now */
    if (p_clcb) bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
    if (p_clcb) {
      /* request read db hash first */
      if (bta_gattc_is_robust_caching_enabled()) {
        p_srcb->srvc_hdl_db_hash = true;
      }
      bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_DISCOVER_EVT, NULL);
    }
  }

  /* notify applicationf or service change */
+175 −56
Original line number Diff line number Diff line
@@ -68,6 +68,15 @@ const Characteristic* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV* p_srcb,
static void bta_gattc_explore_srvc_finished(uint16_t conn_id,
                                            tBTA_GATTC_SERV* p_srvc_cb);

static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb,
                                        tBTA_GATTC_OP_CMPL* p_data);

static void bta_gattc_read_ext_prop_desc_cmpl(tBTA_GATTC_CLCB* p_clcb,
                                              tBTA_GATTC_OP_CMPL* p_data);

// define the max retry count for DATABASE_OUT_OF_SYNC
#define BTA_GATTC_DISCOVER_RETRY_COUNT 2

#define BTA_GATT_SDP_DB_SIZE 4096

#define GATT_CACHE_PREFIX "/data/misc/bluetooth/gatt_cache_"
@@ -170,6 +179,10 @@ static void bta_gattc_explore_next_service(uint16_t conn_id,
  const auto& descriptors =
      p_srvc_cb->pending_discovery.DescriptorHandlesToRead();
  if (!descriptors.empty()) {
    // set request field to READ_EXT_PROP_DESC
    p_clcb->request_during_discovery =
        BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC;

    if (p_srvc_cb->read_multiple_not_supported) {
      tGATT_READ_PARAM read_param{
          .by_handle = {.handle = descriptors.front(),
@@ -226,6 +239,14 @@ static void bta_gattc_explore_srvc_finished(uint16_t conn_id,
                          p_clcb->p_srcb->gatt_database.Serialize());
  }

  // After success, reset the count.
  if (bta_gattc_is_robust_caching_enabled()) {
    LOG(INFO) << __func__
              << ": service discovery succeed, reset count to zero, conn_id="
              << loghex(conn_id);
    p_srvc_cb->srvc_disc_count = 0;
  }

  bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS);
}

@@ -353,63 +374,27 @@ static tGATT_STATUS bta_gattc_sdp_service_disc(uint16_t conn_id,
}

/** operation completed */
void bta_gattc_op_cmpl_during_discovery(UNUSED_ATTR tBTA_GATTC_CLCB* p_clcb,
void bta_gattc_op_cmpl_during_discovery(tBTA_GATTC_CLCB* p_clcb,
                                        tBTA_GATTC_DATA* p_data) {
  uint8_t op = (uint8_t)p_data->op_cmpl.op_code;

  if (op != GATTC_OPTYPE_READ) {
    /* receive op complete when discovery is started, ignore the response,
       and wait for discovery finish and resent */
    VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
    return;
  }
  // our read operation is finished.
  // TODO: check if we can get here when any other read operation i.e. initiated
  // by upper layer apps, can get us there.

  tBTA_GATTC_SERV* p_srvc_cb = p_clcb->p_srcb;
  const uint8_t status = p_data->op_cmpl.status;

  if (status == GATT_REQ_NOT_SUPPORTED &&
      !p_srvc_cb->read_multiple_not_supported) {
    // can't do "read multiple request", fall back to "read request"
    p_srvc_cb->read_multiple_not_supported = true;
    bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
    return;
  }

  if (status != GATT_SUCCESS) {
    LOG(WARNING) << "Discovery on server failed: " << loghex(status);
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
  }

  const tGATT_VALUE& att_value = p_data->op_cmpl.p_cmpl->att_value;
  if (!p_srvc_cb->read_multiple_not_supported && att_value.len != 2) {
    // Just one Characteristic Extended Properties value at a time in Read
    // Response
    LOG(WARNING) << __func__ << " Read Response should be just 2 bytes!";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
  }

  // Parsing is same for "Read Multiple Response", and for "Read Response"
  const uint8_t* p = att_value.value;
  std::vector<uint16_t> value_of_descriptors;
  while (p < att_value.value + att_value.len) {
    uint16_t extended_properties;
    STREAM_TO_UINT16(extended_properties, p);
    value_of_descriptors.push_back(extended_properties);
  // Currently, there are two cases needed to be handled.
  // 1. Read ext prop descriptor value after service discovery
  // 2. Read db hash before starting service discovery
  switch (p_clcb->request_during_discovery) {
    case BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC:
      bta_gattc_read_ext_prop_desc_cmpl(p_clcb, &p_data->op_cmpl);
      break;
    case BTA_GATTC_DISCOVER_REQ_READ_DB_HASH:
      if (bta_gattc_is_robust_caching_enabled()) {
        bta_gattc_read_db_hash_cmpl(p_clcb, &p_data->op_cmpl);
      } else {
        // it is not possible here if flag is off, but just in case
        p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;
      }

  bool ret =
      p_srvc_cb->pending_discovery.SetValueOfDescriptors(value_of_descriptors);
  if (!ret) {
    LOG(WARNING) << __func__
                 << " Problem setting Extended Properties descriptors values";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
      break;
    case BTA_GATTC_DISCOVER_REQ_NONE:
    default:
      break;
  }

  // Continue service discovery
  bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
}

/** callback function to GATT client stack */
@@ -456,14 +441,29 @@ void bta_gattc_disc_res_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
void bta_gattc_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type,
                               tGATT_STATUS status) {
  tBTA_GATTC_CLCB* p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
  tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);

  if (p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS)) {
    if (status == GATT_SUCCESS) p_clcb->status = status;

    // if db out of sync is received, try to start service discovery if possible
    if (bta_gattc_is_robust_caching_enabled() &&
        status == GATT_DATABASE_OUT_OF_SYNC) {
      if (p_srvc_cb &&
          p_srvc_cb->srvc_disc_count < BTA_GATTC_DISCOVER_RETRY_COUNT) {
        p_srvc_cb->srvc_disc_count++;
        p_clcb->auto_update = BTA_GATTC_DISC_WAITING;
      } else {
        LOG(ERROR) << __func__
                   << ": retry limit exceeds for db out of sync, conn_id="
                   << conn_id;
      }
    }

    bta_gattc_sm_execute(p_clcb, BTA_GATTC_DISCOVER_CMPL_EVT, NULL);
    return;
  }

  tBTA_GATTC_SERV* p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id);
  if (!p_srvc_cb) return;

  switch (disc_type) {
@@ -631,6 +631,125 @@ const Characteristic* bta_gattc_get_owning_characteristic(uint16_t conn_id,
  return bta_gattc_get_owning_characteristic_srcb(p_clcb->p_srcb, handle);
}

/* request reading database hash */
bool bta_gattc_read_db_hash(tBTA_GATTC_CLCB* p_clcb) {
  tGATT_READ_PARAM read_param;
  memset(&read_param, 0, sizeof(tGATT_READ_BY_TYPE));

  read_param.char_type.s_handle = 0x0001;
  read_param.char_type.e_handle = 0xFFFF;
  read_param.char_type.uuid = Uuid::From16Bit(GATT_UUID_DATABASE_HASH);
  read_param.char_type.auth_req = GATT_AUTH_REQ_NONE;
  tGATT_STATUS status =
      GATTC_Read(p_clcb->bta_conn_id, GATT_READ_BY_TYPE, &read_param);

  if (status != GATT_SUCCESS) return false;
  p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_READ_DB_HASH;

  return true;
}

/* handle response of reading database hash */
static void bta_gattc_read_db_hash_cmpl(tBTA_GATTC_CLCB* p_clcb,
                                        tBTA_GATTC_OP_CMPL* p_data) {
  uint8_t op = (uint8_t)p_data->op_code;
  if (op != GATTC_OPTYPE_READ) {
    VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
    return;
  }
  p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;

  // run match flow only if the status is success
  bool matched = false;
  if (p_data->status == GATT_SUCCESS) {
    // start to compare local hash and remote hash
    uint16_t len = p_data->p_cmpl->att_value.len;
    uint8_t* data = p_data->p_cmpl->att_value.value;

    Octet16 remote_hash;
    if (len == remote_hash.size()) {
      uint8_t idx = 0;
      auto it = remote_hash.begin();
      for (; idx < len; idx++, data++, it++) *it = *data;

      Octet16 local_hash = p_clcb->p_srcb->gatt_database.Hash();
      matched = (local_hash == remote_hash);
    }
  }

  if (matched) {
    LOG(INFO) << __func__ << ": hash is the same, skip service discovery";
    p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_SUCCESS);
  } else {
    LOG(INFO) << __func__ << ": hash is not the same, start service discovery";
    bta_gattc_start_discover_internal(p_clcb);
  }
}

/* handle response of reading extended properties descriptor */
static void bta_gattc_read_ext_prop_desc_cmpl(tBTA_GATTC_CLCB* p_clcb,
                                              tBTA_GATTC_OP_CMPL* p_data) {
  uint8_t op = (uint8_t)p_data->op_code;
  if (op != GATTC_OPTYPE_READ) {
    VLOG(1) << __func__ << ": op = " << +p_data->hdr.layer_specific;
    return;
  }

  if (!p_clcb->disc_active) {
    VLOG(1) << __func__ << ": not active in discover state";
    return;
  }
  p_clcb->request_during_discovery = BTA_GATTC_DISCOVER_REQ_NONE;

  tBTA_GATTC_SERV* p_srvc_cb = p_clcb->p_srcb;
  const uint8_t status = p_data->status;

  if (status == GATT_REQ_NOT_SUPPORTED &&
      !p_srvc_cb->read_multiple_not_supported) {
    // can't do "read multiple request", fall back to "read request"
    p_srvc_cb->read_multiple_not_supported = true;
    bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
    return;
  }

  if (status != GATT_SUCCESS) {
    LOG(WARNING) << "Discovery on server failed: " << loghex(status);
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
    return;
  }

  const tGATT_VALUE& att_value = p_data->p_cmpl->att_value;
  if (p_srvc_cb->read_multiple_not_supported && att_value.len != 2) {
    // Just one Characteristic Extended Properties value at a time in Read
    // Response
    LOG(WARNING) << __func__ << " Read Response should be just 2 bytes!";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
    return;
  }

  // Parsing is same for "Read Multiple Response", and for "Read Response"
  const uint8_t* p = att_value.value;
  std::vector<uint16_t> value_of_descriptors;
  while (p < att_value.value + att_value.len) {
    uint16_t extended_properties;
    STREAM_TO_UINT16(extended_properties, p);
    value_of_descriptors.push_back(extended_properties);
  }

  bool ret =
      p_srvc_cb->pending_discovery.SetValueOfDescriptors(value_of_descriptors);
  if (!ret) {
    LOG(WARNING) << __func__
                 << " Problem setting Extended Properties descriptors values";
    bta_gattc_reset_discover_st(p_clcb->p_srcb, GATT_ERROR);
    return;
  }

  // Continue service discovery
  bta_gattc_explore_next_service(p_clcb->bta_conn_id, p_srvc_cb);
}

/*******************************************************************************
 *
 * Function         bta_gattc_fill_gatt_db_el
+13 −0
Original line number Diff line number Diff line
@@ -219,6 +219,8 @@ typedef struct {
  bool read_multiple_not_supported;

  uint8_t srvc_hdl_chg; /* service handle change indication pending */
  bool srvc_hdl_db_hash;   /* read db hash pending */
  uint8_t srvc_disc_count; /* current discovery retry count */
  uint16_t attr_index;  /* cahce NV saving/loading attribute index */

  uint16_t mtu;
@@ -254,6 +256,13 @@ typedef struct {
  tBTA_GATTC_SERV* p_srcb;  /* server cache CB */
  tBTA_GATTC_DATA* p_q_cmd; /* command in queue waiting for execution */

// request during discover state
#define BTA_GATTC_DISCOVER_REQ_NONE 0
#define BTA_GATTC_DISCOVER_REQ_READ_EXT_PROP_DESC 1
#define BTA_GATTC_DISCOVER_REQ_READ_DB_HASH 2

  uint8_t request_during_discovery; /* request during discover state */

#define BTA_GATTC_NO_SCHEDULE 0
#define BTA_GATTC_DISC_WAITING 0x01
#define BTA_GATTC_REQ_WAITING 0x10
@@ -352,6 +361,7 @@ extern void bta_gattc_disc_close(tBTA_GATTC_CLCB* p_clcb,

extern void bta_gattc_start_discover(tBTA_GATTC_CLCB* p_clcb,
                                     tBTA_GATTC_DATA* p_data);
extern void bta_gattc_start_discover_internal(tBTA_GATTC_CLCB* p_clcb);
extern void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB* p_clcb,
                                tBTA_GATTC_DATA* p_data);
extern void bta_gattc_read(tBTA_GATTC_CLCB* p_clcb, tBTA_GATTC_DATA* p_data);
@@ -418,6 +428,7 @@ extern void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV* p_srcb,
                                               uint16_t start_handle,
                                               uint16_t end_handle);
extern tBTA_GATTC_SERV* bta_gattc_find_srvr_cache(const RawAddress& bda);
extern bool bta_gattc_is_robust_caching_enabled();

/* discovery functions */
extern void bta_gattc_disc_res_cback(uint16_t conn_id,
@@ -459,4 +470,6 @@ extern bool bta_gattc_conn_dealloc(const RawAddress& remote_bda);
extern bool bta_gattc_cache_load(tBTA_GATTC_SERV* p_srcb);
extern void bta_gattc_cache_reset(const RawAddress& server_bda);

extern bool bta_gattc_read_db_hash(tBTA_GATTC_CLCB* p_clcb);

#endif /* BTA_GATTC_INT_H */
Loading