/******************************************************************************
 *
 *  Copyright (C) 2009-2016 Broadcom Corporation
 *
 *  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.
 *
 ******************************************************************************/

#define LOG_TAG "btif_av"

#include "btif_av.h"

#include <base/logging.h>
#include <string.h>

#include <hardware/bluetooth.h>
#include <hardware/bt_av.h>
#include <hardware/bt_rc.h>

#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
#include "bt_common.h"
#include "bt_utils.h"
#include "bta_api.h"
#include "btif_a2dp.h"
#include "btif_a2dp_control.h"
#include "btif_a2dp_sink.h"
#include "btif_av_co.h"
#include "btif_profile_queue.h"
#include "btif_util.h"
#include "btu.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"

/*****************************************************************************
 *  Constants & Macros
 *****************************************************************************/
#define BTIF_AV_SERVICE_NAME "Advanced Audio"
#define BTIF_AVK_SERVICE_NAME "Advanced Audio Sink"

#define BTIF_TIMEOUT_AV_OPEN_ON_RC_MS (2 * 1000)

typedef enum {
  BTIF_AV_STATE_IDLE = 0x0,
  BTIF_AV_STATE_OPENING,
  BTIF_AV_STATE_OPENED,
  BTIF_AV_STATE_STARTED,
  BTIF_AV_STATE_CLOSING
} btif_av_state_t;

/* Should not need dedicated suspend state as actual actions are no
   different than open state. Suspend flags are needed however to prevent
   media task from trying to restart stream during remote suspend or while
   we are in the process of a local suspend */

#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
#define BTIF_AV_FLAG_REMOTE_SUSPEND 0x2
#define BTIF_AV_FLAG_PENDING_START 0x4
#define BTIF_AV_FLAG_PENDING_STOP 0x8

/*****************************************************************************
 *  Local type definitions
 *****************************************************************************/

typedef struct {
  tBTA_AV_HNDL bta_handle;
  RawAddress peer_bda;
  bool self_initiated_connection;
  btif_sm_handle_t sm_handle;
  uint8_t flags;
  tBTA_AV_EDR edr;
  uint8_t peer_sep; /* sep type of peer device */
  std::vector<btav_a2dp_codec_config_t> codec_priorities;
} btif_av_cb_t;

typedef struct {
  RawAddress* target_bda;
  uint16_t uuid;
} btif_av_connect_req_t;

typedef struct {
  int sample_rate;
  int channel_count;
  RawAddress peer_bd;
} btif_av_sink_config_req_t;

/*****************************************************************************
 *  Static variables
 *****************************************************************************/
static btav_source_callbacks_t* bt_av_src_callbacks = NULL;
static btav_sink_callbacks_t* bt_av_sink_callbacks = NULL;
static btif_av_cb_t btif_av_cb = {
    0, {{0}}, false, 0, 0, 0, 0, std::vector<btav_a2dp_codec_config_t>()};
static alarm_t* av_open_on_rc_timer = NULL;

/* both interface and media task needs to be ready to alloc incoming request */
#define CHECK_BTAV_INIT()                                                    \
  do {                                                                       \
    if (((bt_av_src_callbacks == NULL) && (bt_av_sink_callbacks == NULL)) || \
        (btif_av_cb.sm_handle == NULL)) {                                    \
      BTIF_TRACE_WARNING("%s: BTAV not initialized", __func__);              \
      return BT_STATUS_NOT_READY;                                            \
    }                                                                        \
  } while (0)

/* Helper macro to avoid code duplication in the state machine handlers */
#define CHECK_RC_EVENT(e, d)       \
  case BTA_AV_RC_OPEN_EVT:         \
  case BTA_AV_RC_BROWSE_OPEN_EVT:  \
  case BTA_AV_RC_CLOSE_EVT:        \
  case BTA_AV_RC_BROWSE_CLOSE_EVT: \
  case BTA_AV_REMOTE_CMD_EVT:      \
  case BTA_AV_VENDOR_CMD_EVT:      \
  case BTA_AV_META_MSG_EVT:        \
  case BTA_AV_RC_FEAT_EVT:         \
  case BTA_AV_REMOTE_RSP_EVT: {    \
    btif_rc_handler(e, d);         \
  } break;

static bool btif_av_state_idle_handler(btif_sm_event_t event, void* data);
static bool btif_av_state_opening_handler(btif_sm_event_t event, void* data);
static bool btif_av_state_opened_handler(btif_sm_event_t event, void* data);
static bool btif_av_state_started_handler(btif_sm_event_t event, void* data);
static bool btif_av_state_closing_handler(btif_sm_event_t event, void* data);

static const btif_sm_handler_t btif_av_state_handlers[] = {
    btif_av_state_idle_handler, btif_av_state_opening_handler,
    btif_av_state_opened_handler, btif_av_state_started_handler,
    btif_av_state_closing_handler};

static void btif_av_event_free_data(btif_sm_event_t event, void* p_data);

/*************************************************************************
 * Extern functions
 ************************************************************************/
extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data);
extern bool btif_rc_get_connected_peer(RawAddress* peer_addr);
extern uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr);
extern void btif_rc_check_handle_pending_play(const RawAddress& peer_addr,
                                              bool bSendToApp);

/*****************************************************************************
 * Local helper functions
 *****************************************************************************/

const char* dump_av_sm_state_name(btif_av_state_t state) {
  switch (state) {
    CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
    CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
    CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
    CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
    CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
    default:
      return "UNKNOWN_STATE";
  }
}

const char* dump_av_sm_event_name(btif_av_sm_event_t event) {
  switch ((int)event) {
    CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
    CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
    CASE_RETURN_STR(BTA_AV_OPEN_EVT)
    CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
    CASE_RETURN_STR(BTA_AV_START_EVT)
    CASE_RETURN_STR(BTA_AV_STOP_EVT)
    CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
    CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
    CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
    CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
    CASE_RETURN_STR(BTA_AV_RC_BROWSE_OPEN_EVT)
    CASE_RETURN_STR(BTA_AV_RC_BROWSE_CLOSE_EVT)
    CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
    CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
    CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
    CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
    CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
    CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
    CASE_RETURN_STR(BTA_AV_PENDING_EVT)
    CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
    CASE_RETURN_STR(BTA_AV_REJECT_EVT)
    CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
    CASE_RETURN_STR(BTA_AV_OFFLOAD_START_RSP_EVT)
    CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
    CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
    CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_SOURCE_CONFIG_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_SOURCE_CONFIG_UPDATED_EVT)
    CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
    CASE_RETURN_STR(BTIF_AV_OFFLOAD_START_REQ_EVT)
    default:
      return "UNKNOWN_EVENT";
  }
}

/****************************************************************************
 *  Local helper functions
 ****************************************************************************/
/*******************************************************************************
 *
 * Function         btif_initiate_av_open_timer_timeout
 *
 * Description      Timer to trigger AV open if the remote headset establishes
 *                  RC connection w/o AV connection. The timer is needed to IOP
 *                  with headsets that do establish AV after RC connection.
 *
 * Returns          void
 *
 ******************************************************************************/
static void btif_initiate_av_open_timer_timeout(UNUSED_ATTR void* data) {
  RawAddress peer_addr;
  btif_av_connect_req_t connect_req;

  /* is there at least one RC connection - There should be */
  if (btif_rc_get_connected_peer(&peer_addr)) {
    BTIF_TRACE_DEBUG("%s: Issuing connect to the remote RC peer", __func__);
    /* In case of AVRCP connection request, we will initiate SRC connection */
    connect_req.target_bda = &peer_addr;
    if (bt_av_sink_callbacks != NULL)
      connect_req.uuid = UUID_SERVCLASS_AUDIO_SINK;
    else if (bt_av_src_callbacks != NULL)
      connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
    btif_dispatch_sm_event(BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req,
                           sizeof(connect_req));
  } else {
    BTIF_TRACE_ERROR("%s: No connected RC peers", __func__);
  }
}

/*****************************************************************************
 *  Static functions
 *****************************************************************************/

/*******************************************************************************
 *
 * Function         btif_report_connection_state
 *
 * Description      Updates the components via the callbacks about the
 *                  connection state of a2dp connection.
 *
 * Returns          None
 *
 ******************************************************************************/
static void btif_report_connection_state(btav_connection_state_t state,
                                         RawAddress* bd_addr) {
  if (bt_av_sink_callbacks != NULL) {
    HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
  } else if (bt_av_src_callbacks != NULL) {
    HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
  }
}

/*******************************************************************************
 *
 * Function         btif_report_audio_state
 *
 * Description      Updates the components via the callbacks about the audio
 *                  state of a2dp connection. The state is updated when either
 *                  the remote ends starts streaming (started state) or whenever
 *                  it transitions out of started state (to opened or streaming)
 *                  state.
 *
 * Returns          None
 *
 ******************************************************************************/
static void btif_report_audio_state(btav_audio_state_t state,
                                    RawAddress* bd_addr) {
  if (bt_av_sink_callbacks != NULL) {
    HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
  } else if (bt_av_src_callbacks != NULL) {
    HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
  }
}

static void btif_update_source_codec(void* p_data) {
  BTIF_TRACE_DEBUG("%s", __func__);

  // copy to avoid alignment problems
  btav_a2dp_codec_config_t req;
  memcpy(&req, p_data, sizeof(req));

  btif_a2dp_source_encoder_user_config_update_req(req);
}

static void btif_report_source_codec_state(UNUSED_ATTR void* p_data) {
  btav_a2dp_codec_config_t codec_config;
  std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities;
  std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities;

  A2dpCodecs* a2dp_codecs = bta_av_get_a2dp_codecs();
  if (a2dp_codecs == nullptr) return;
  if (!a2dp_codecs->getCodecConfigAndCapabilities(
          &codec_config, &codecs_local_capabilities,
          &codecs_selectable_capabilities)) {
    BTIF_TRACE_WARNING(
        "%s: error reporting audio source codec state: "
        "cannot get codec config and capabilities",
        __func__);
    return;
  }
  if (bt_av_src_callbacks != NULL) {
    HAL_CBACK(bt_av_src_callbacks, audio_config_cb, codec_config,
              codecs_local_capabilities, codecs_selectable_capabilities);
  }
}

/*****************************************************************************
 *
 * Function     btif_av_state_idle_handler
 *
 * Description  State managing disconnected AV link
 *
 * Returns      true if event was processed, false otherwise
 *
 ******************************************************************************/

static bool btif_av_state_idle_handler(btif_sm_event_t event, void* p_data) {
  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                   dump_av_sm_event_name((btif_av_sm_event_t)event),
                   btif_av_cb.flags);

  switch (event) {
    case BTIF_SM_ENTER_EVT:
      /* clear the peer_bda */
      btif_av_cb.peer_bda = RawAddress::kEmpty;
      btif_av_cb.flags = 0;
      btif_av_cb.edr = 0;
      bta_av_co_init(btif_av_cb.codec_priorities);
      btif_a2dp_on_idle();
      break;

    case BTIF_SM_EXIT_EVT:
      break;

    case BTA_AV_ENABLE_EVT:
      break;

    case BTA_AV_REGISTER_EVT:
      btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
      break;

    case BTA_AV_PENDING_EVT:
    case BTIF_AV_CONNECT_REQ_EVT: {
      if (event == BTIF_AV_CONNECT_REQ_EVT) {
        btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
        btif_av_cb.peer_bda = *connect_req_p->target_bda;
        btif_av_cb.self_initiated_connection = true;
        BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                   BTA_SEC_AUTHENTICATE, connect_req_p->uuid);
      } else if (event == BTA_AV_PENDING_EVT) {
        btif_av_cb.peer_bda = ((tBTA_AV*)p_data)->pend.bd_addr;
        btif_av_cb.self_initiated_connection = false;
        if (bt_av_src_callbacks != NULL) {
          BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                     BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
        }
        if (bt_av_sink_callbacks != NULL) {
          BTA_AvOpen(btif_av_cb.peer_bda, btif_av_cb.bta_handle, true,
                     BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SINK);
        }
      }
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
    } break;

    case BTA_AV_RC_OPEN_EVT:
      /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it
       * connects. So
       * as per the AV WP, an AVRC connection cannot exist without an AV
       * connection. Therefore,
       * we initiate an AV connection if an RC_OPEN_EVT is received when we are
       * in AV_CLOSED state.
       * We initiate the AV connection after a small 3s timeout to avoid any
       * collisions from the
       * headsets, as some headsets initiate the AVRC connection first and then
       * immediately initiate the AV connection
       *
       * TODO: We may need to do this only on an AVRCP Play. FixMe
       */

      BTIF_TRACE_WARNING("%s: BTA_AV_RC_OPEN_EVT received w/o AV", __func__);
      alarm_set_on_mloop(av_open_on_rc_timer, BTIF_TIMEOUT_AV_OPEN_ON_RC_MS,
                         btif_initiate_av_open_timer_timeout, NULL);
      btif_rc_handler(event, (tBTA_AV*)p_data);
      break;

    case BTA_AV_RC_BROWSE_OPEN_EVT:
      BTIF_TRACE_DEBUG("%s: BTA_AV_RC_BROWSE_OPEN_EVT received", __func__);
      btif_rc_handler(event, (tBTA_AV*)p_data);
      break;

    case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
      btif_update_source_codec(p_data);
      break;

    case BTIF_AV_SOURCE_CONFIG_UPDATED_EVT:
      btif_report_source_codec_state(p_data);
      break;

    /*
     * In case Signalling channel is not down
     * and remote started Streaming Procedure
     * we have to handle config and open event in
     * idle_state. We hit these scenarios while running
     * PTS test case for AVRCP Controller
     */
    case BTIF_AV_SINK_CONFIG_REQ_EVT: {
      btif_av_sink_config_req_t req;
      // copy to avoid alignment problems
      memcpy(&req, p_data, sizeof(req));

      BTIF_TRACE_WARNING(
          "%s: BTIF_AV_SINK_CONFIG_REQ_EVT sample_rate=%d "
          "channel_count=%d",
          __func__, req.sample_rate, req.channel_count);
      if (bt_av_sink_callbacks != NULL) {
        HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(req.peer_bd),
                  req.sample_rate, req.channel_count);
      }
    } break;

    case BTA_AV_OPEN_EVT: {
      tBTA_AV* p_bta_data = (tBTA_AV*)p_data;
      btav_connection_state_t state;
      btif_sm_state_t av_state;
      BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT status=%d, edr=0x%x", __func__,
                         p_bta_data->open.status, p_bta_data->open.edr);

      if (p_bta_data->open.status == BTA_AV_SUCCESS) {
        state = BTAV_CONNECTION_STATE_CONNECTED;
        av_state = BTIF_AV_STATE_OPENED;
        btif_av_cb.edr = p_bta_data->open.edr;

        btif_av_cb.peer_sep = p_bta_data->open.sep;
      } else {
        BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT::FAILED status=%d", __func__,
                           p_bta_data->open.status);
        state = BTAV_CONNECTION_STATE_DISCONNECTED;
        av_state = BTIF_AV_STATE_IDLE;
      }

      /* inform the application of the event */
      btif_report_connection_state(state, &(btif_av_cb.peer_bda));
      /* change state to open/idle based on the status */
      btif_sm_change_state(btif_av_cb.sm_handle, av_state);
      if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
        /* if queued PLAY command,  send it now */
        btif_rc_check_handle_pending_play(
            p_bta_data->open.bd_addr,
            (p_bta_data->open.status == BTA_AV_SUCCESS));
      } else if ((btif_av_cb.peer_sep == AVDT_TSEP_SRC) &&
                 (p_bta_data->open.status == BTA_AV_SUCCESS)) {
        /* Bring up AVRCP connection too */
        BTA_AvOpenRc(btif_av_cb.bta_handle);
      }
      btif_queue_advance();
    } break;

    case BTA_AV_REMOTE_CMD_EVT:
    case BTA_AV_VENDOR_CMD_EVT:
    case BTA_AV_META_MSG_EVT:
    case BTA_AV_RC_FEAT_EVT:
    case BTA_AV_REMOTE_RSP_EVT:
      btif_rc_handler(event, (tBTA_AV*)p_data);
      break;

    case BTA_AV_RC_CLOSE_EVT:
      BTIF_TRACE_DEBUG("%s: BTA_AV_RC_CLOSE_EVT: Stopping AV timer.", __func__);
      alarm_cancel(av_open_on_rc_timer);
      btif_rc_handler(event, (tBTA_AV*)p_data);
      break;

    case BTIF_AV_OFFLOAD_START_REQ_EVT:
      BTIF_TRACE_ERROR(
          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started IDLE",
          __func__);
      btif_a2dp_on_offload_started(BTA_AV_FAIL);
      break;

    default:
      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event));
      return false;
  }

  return true;
}
/*****************************************************************************
 *
 * Function        btif_av_state_opening_handler
 *
 * Description     Intermediate state managing events during establishment
 *                 of avdtp channel
 *
 * Returns         true if event was processed, false otherwise
 *
 ******************************************************************************/

static bool btif_av_state_opening_handler(btif_sm_event_t event, void* p_data) {
  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                   dump_av_sm_event_name((btif_av_sm_event_t)event),
                   btif_av_cb.flags);

  switch (event) {
    case BTIF_SM_ENTER_EVT:
      /* inform the application that we are entering connecting state */
      btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING,
                                   &(btif_av_cb.peer_bda));
      break;

    case BTIF_SM_EXIT_EVT:
      break;

    case BTA_AV_REJECT_EVT:
      BTIF_TRACE_WARNING("%s: Received BTA_AV_REJECT_EVT", __func__);
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
      break;

    case BTA_AV_OPEN_EVT: {
      tBTA_AV* p_bta_data = (tBTA_AV*)p_data;
      btav_connection_state_t state;
      btif_sm_state_t av_state;
      BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT status=%d, edr=0x%x", __func__,
                         p_bta_data->open.status, p_bta_data->open.edr);

      if (p_bta_data->open.status == BTA_AV_SUCCESS) {
        state = BTAV_CONNECTION_STATE_CONNECTED;
        av_state = BTIF_AV_STATE_OPENED;
        btif_av_cb.edr = p_bta_data->open.edr;

        btif_av_cb.peer_sep = p_bta_data->open.sep;
      } else {
        BTIF_TRACE_WARNING("%s: BTA_AV_OPEN_EVT::FAILED status: %d", __func__,
                           p_bta_data->open.status);
        RawAddress peer_addr;
        uint8_t peer_handle = BTRC_HANDLE_NONE;
        if (btif_rc_get_connected_peer(&peer_addr) &&
            btif_av_cb.peer_bda == peer_addr) {
          /*
           * Disconnect AVRCP connection, if
           * A2DP conneciton failed, for any reason
           */
          BTIF_TRACE_WARNING("%s: Disconnecting AVRCP: peer_addr=%s", __func__,
                             peer_addr.ToString().c_str());
          peer_handle = btif_rc_get_connected_peer_handle(peer_addr);
          if (peer_handle != BTRC_HANDLE_NONE) {
            BTA_AvCloseRc(peer_handle);
          }
        }
        state = BTAV_CONNECTION_STATE_DISCONNECTED;
        av_state = BTIF_AV_STATE_IDLE;
      }

      /* inform the application of the event */
      btif_report_connection_state(state, &(btif_av_cb.peer_bda));
      /* change state to open/idle based on the status */
      btif_sm_change_state(btif_av_cb.sm_handle, av_state);
      if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
        /* if queued PLAY command,  send it now */
        btif_rc_check_handle_pending_play(
            p_bta_data->open.bd_addr,
            (p_bta_data->open.status == BTA_AV_SUCCESS));
      } else if ((btif_av_cb.peer_sep == AVDT_TSEP_SRC) &&
                 (p_bta_data->open.status == BTA_AV_SUCCESS)) {
        /* Bring up AVRCP connection too */
        BTA_AvOpenRc(btif_av_cb.bta_handle);
      }
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
    } break;

    case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
      btif_update_source_codec(p_data);
      break;

    case BTIF_AV_SOURCE_CONFIG_UPDATED_EVT:
      btif_report_source_codec_state(p_data);
      break;

    case BTIF_AV_SINK_CONFIG_REQ_EVT: {
      btif_av_sink_config_req_t req;
      // copy to avoid alignment problems
      memcpy(&req, p_data, sizeof(req));

      BTIF_TRACE_WARNING(
          "%s: BTIF_AV_SINK_CONFIG_REQ_EVT sample_rate=%d "
          "channel_count=%d",
          __func__, req.sample_rate, req.channel_count);
      if (btif_av_cb.peer_sep == AVDT_TSEP_SRC &&
          bt_av_sink_callbacks != NULL) {
        HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
                  req.sample_rate, req.channel_count);
      }
    } break;

    case BTIF_AV_CONNECT_REQ_EVT: {
      // Check for device, if same device which moved to opening then ignore
      // callback
      btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
      RawAddress& target_bda = *connect_req_p->target_bda;
      if (btif_av_cb.peer_bda == target_bda) {
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, ignore Connect request",
            __func__, btif_av_cb.peer_bda.ToString().c_str());
      } else {
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, reject Connect request to %s",
            __func__, btif_av_cb.peer_bda.ToString().c_str(),
            target_bda.ToString().c_str());
        btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                     &target_bda);
      }
      // Ignore all connection request if we are already opening
      btif_queue_advance();
    } break;

    case BTA_AV_PENDING_EVT: {
      // Check for device, if same device which moved to opening then ignore
      // callback
      const RawAddress& bd_addr = ((tBTA_AV*)p_data)->pend.bd_addr;
      if (bd_addr == btif_av_cb.peer_bda) {
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, ignore incoming request",
            __func__, btif_av_cb.peer_bda.ToString().c_str());
      } else {
        BTIF_TRACE_WARNING(
            "%s: device %s is already connecting, reject incoming request "
            "from %s",
            __func__, btif_av_cb.peer_bda.ToString().c_str(),
            bd_addr.ToString().c_str());
        BTA_AvDisconnect(bd_addr);
      }
    } break;

    case BTIF_AV_OFFLOAD_START_REQ_EVT:
      BTIF_TRACE_ERROR(
          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started OPENING",
          __func__);
      btif_a2dp_on_offload_started(BTA_AV_FAIL);
      break;

    case BTA_AV_CLOSE_EVT:
      btif_a2dp_on_stopped(NULL);
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
      break;

    case BTIF_AV_DISCONNECT_REQ_EVT:
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));
      BTA_AvClose(btif_av_cb.bta_handle);
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      if (btif_av_cb.self_initiated_connection) {
        btif_queue_advance();
      }
      break;

      CHECK_RC_EVENT(event, (tBTA_AV*)p_data);

    default:
      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event));
      return false;
  }
  return true;
}

/*****************************************************************************
 *
 * Function        btif_av_state_closing_handler
 *
 * Description     Intermediate state managing events during closing
 *                 of avdtp channel
 *
 * Returns         true if event was processed, false otherwise
 *
 ******************************************************************************/

static bool btif_av_state_closing_handler(btif_sm_event_t event, void* p_data) {
  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                   dump_av_sm_event_name((btif_av_sm_event_t)event),
                   btif_av_cb.flags);

  switch (event) {
    case BTIF_SM_ENTER_EVT:
      if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
        /* immediately stop transmission of frames */
        btif_a2dp_source_set_tx_flush(true);
        /* wait for audioflinger to stop a2dp */
      }
      if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
        btif_a2dp_sink_set_rx_flush(true);
      }
      break;

    case BTA_AV_STOP_EVT:
    case BTIF_AV_STOP_STREAM_REQ_EVT:
      btif_a2dp_on_stopped(NULL);
      break;

    case BTIF_SM_EXIT_EVT:
      break;

    case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
      btif_update_source_codec(p_data);
      break;

    case BTIF_AV_SOURCE_CONFIG_UPDATED_EVT:
      btif_report_source_codec_state(p_data);
      break;

    case BTA_AV_CLOSE_EVT:

      /* inform the application that we are disconnecting */
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));

      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      break;

    /* Handle the RC_CLOSE event for the cleanup */
    case BTA_AV_RC_CLOSE_EVT:
      btif_rc_handler(event, (tBTA_AV*)p_data);
      break;

    /* Handle the RC_BROWSE_CLOSE event for tetsing*/
    case BTA_AV_RC_BROWSE_CLOSE_EVT:
      btif_rc_handler(event, (tBTA_AV*)p_data);
      break;

    case BTIF_AV_OFFLOAD_START_REQ_EVT:
      BTIF_TRACE_ERROR(
          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Closing",
          __func__);
      btif_a2dp_on_offload_started(BTA_AV_FAIL);
      break;

    default:
      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event));
      return false;
  }
  return true;
}

/*****************************************************************************
 *
 * Function     btif_av_state_opened_handler
 *
 * Description  Handles AV events while AVDTP is in OPEN state
 *
 * Returns      true if event was processed, false otherwise
 *
 ******************************************************************************/

static bool btif_av_state_opened_handler(btif_sm_event_t event, void* p_data) {
  tBTA_AV* p_av = (tBTA_AV*)p_data;

  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                   dump_av_sm_event_name((btif_av_sm_event_t)event),
                   btif_av_cb.flags);

  if ((event == BTA_AV_REMOTE_CMD_EVT) &&
      (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
      (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY)) {
    BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __func__);
    btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
  }

  switch (event) {
    case BTIF_SM_ENTER_EVT:
      btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
      btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
      break;

    case BTIF_SM_EXIT_EVT:
      btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
      break;

    case BTIF_AV_START_STREAM_REQ_EVT:
      if (btif_av_cb.peer_sep != AVDT_TSEP_SRC) btif_a2dp_source_setup_codec();
      BTA_AvStart();
      btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
      break;

    case BTA_AV_START_EVT: {
      BTIF_TRACE_WARNING(
          "%s: BTA_AV_START_EVT status=%d suspending=%d initiator=%d "
          "flags=0x%x",
          __func__, p_av->start.status, p_av->start.suspending,
          p_av->start.initiator, btif_av_cb.flags);

      if ((p_av->start.status == BTA_SUCCESS) &&
          (p_av->start.suspending == true))
        return true;

      /* if remote tries to start a2dp when DUT is a2dp source
       * then suspend. In case a2dp is sink and call is active
       * then disconnect the AVDTP channel
       */
      if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)) {
        if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
          BTIF_TRACE_WARNING("%s: trigger suspend as remote initiated!!",
                             __func__);
          btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
        }
      }

      /*  In case peer is A2DP SRC we do not want to ack commands on UIPC*/
      if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
        if (btif_a2dp_on_started(
                &p_av->start,
                ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0))) {
          /* only clear pending flag after acknowledgement */
          btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
        }
      }

      /* remain in open state if status failed */
      if (p_av->start.status != BTA_AV_SUCCESS) return false;

      if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
        btif_a2dp_sink_set_rx_flush(
            false); /*  remove flush state, ready for streaming*/
      }

      /* change state to started, send acknowledgement if start is pending */
      if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
        if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
          btif_a2dp_on_started(NULL, true);
        /* pending start flag will be cleared when exit current state */
      }
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);

    } break;

    case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
      btif_update_source_codec(p_data);
      break;

    case BTIF_AV_SOURCE_CONFIG_UPDATED_EVT:
      btif_report_source_codec_state(p_data);
      break;

    case BTIF_AV_DISCONNECT_REQ_EVT:
      BTA_AvClose(btif_av_cb.bta_handle);
      if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
        BTA_AvCloseRc(btif_av_cb.bta_handle);
      }

      /* inform the application that we are disconnecting */
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING,
                                   &(btif_av_cb.peer_bda));
      break;

    case BTA_AV_CLOSE_EVT:
      /* avdtp link is closed */
      btif_a2dp_on_stopped(NULL);

      /* inform the application that we are disconnected */
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));

      /* change state to idle, send acknowledgement if start is pending */
      if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
        btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
        /* pending start flag will be cleared when exit current state */
      }
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      break;

    case BTA_AV_RECONFIG_EVT:
      if ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
          (p_av->reconfig.status == BTA_AV_SUCCESS)) {
        APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
        BTA_AvStart();
      } else if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
        btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
        btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE);
      }
      break;

    case BTIF_AV_CONNECT_REQ_EVT: {
      btif_av_connect_req_t* connect_req_p = (btif_av_connect_req_t*)p_data;
      RawAddress& target_bda = *connect_req_p->target_bda;
      if (btif_av_cb.peer_bda == target_bda) {
        BTIF_TRACE_WARNING(
            "%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device: target_bda=%s",
            __func__, target_bda.ToString().c_str());
      } else {
        BTIF_TRACE_WARNING(
            "%s: Moved to opened by Other incoming Connect request: "
            "target_bda=%s",
            __func__, target_bda.ToString().c_str());
        btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                     &target_bda);
      }
      btif_queue_advance();
    } break;

    case BTIF_AV_OFFLOAD_START_REQ_EVT:
      BTIF_TRACE_ERROR(
          "%s: BTIF_AV_OFFLOAD_START_REQ_EVT: Stream not Started Opened",
          __func__);
      btif_a2dp_on_offload_started(BTA_AV_FAIL);
      break;

      CHECK_RC_EVENT(event, (tBTA_AV*)p_data);

    default:
      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event));
      return false;
  }
  return true;
}

/*****************************************************************************
 *
 * Function     btif_av_state_started_handler
 *
 * Description  Handles AV events while A2DP stream is started
 *
 * Returns      true if event was processed, false otherwise
 *
 ******************************************************************************/

static bool btif_av_state_started_handler(btif_sm_event_t event, void* p_data) {
  tBTA_AV* p_av = (tBTA_AV*)p_data;

  BTIF_TRACE_DEBUG("%s: event=%s flags=0x%x", __func__,
                   dump_av_sm_event_name((btif_av_sm_event_t)event),
                   btif_av_cb.flags);

  switch (event) {
    case BTIF_SM_ENTER_EVT:

      /* we are again in started state, clear any remote suspend flags */
      btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;

      /**
       * Report to components above that we have entered the streaming
       * stage, this should usually be followed by focus grant.
       * see update_audio_focus_state()
       */
      btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
      break;

    case BTIF_SM_EXIT_EVT:
      break;

    case BTIF_AV_START_STREAM_REQ_EVT:
      /* we were remotely started, just ack back the local request */
      if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
        btif_a2dp_on_started(NULL, true);
      break;

    case BTIF_AV_SOURCE_CONFIG_REQ_EVT:
      btif_update_source_codec(p_data);
      break;

    case BTIF_AV_SOURCE_CONFIG_UPDATED_EVT:
      btif_report_source_codec_state(p_data);
      break;

    /* fixme -- use suspend = true always to work around issue with BTA AV */
    case BTIF_AV_STOP_STREAM_REQ_EVT:
    case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event),
                         btif_av_cb.flags);
      /* set pending flag to ensure btif task is not trying to restart
         stream while suspend is in progress */
      btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;

      /* if we were remotely suspended but suspend locally, local suspend
         always overrides */
      btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;

      if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
        /*
         * Immediately stop transmission of frames while suspend is
         * pending.
         */
        btif_a2dp_source_set_tx_flush(true);
      }

      if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
        btif_a2dp_on_stopped(NULL);
      }

      BTA_AvStop(true);
      break;

    case BTIF_AV_DISCONNECT_REQ_EVT:
      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event),
                         btif_av_cb.flags);

      /* request avdtp to close */
      BTA_AvClose(btif_av_cb.bta_handle);
      if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
        BTA_AvCloseRc(btif_av_cb.bta_handle);
      }

      /* inform the application that we are disconnecting */
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING,
                                   &(btif_av_cb.peer_bda));

      /* wait in closing state until fully closed */
      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
      break;

    case BTA_AV_SUSPEND_EVT:
      BTIF_TRACE_WARNING(
          "%s: BTA_AV_SUSPEND_EVT status=%d initiator=%d flags=0x%x", __func__,
          p_av->suspend.status, p_av->suspend.initiator, btif_av_cb.flags);

      /* a2dp suspended, stop media task until resumed */
      btif_a2dp_on_suspended(&p_av->suspend);

      /* if not successful, remain in current state */
      if (p_av->suspend.status != BTA_AV_SUCCESS) {
        btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;

        if (btif_av_cb.peer_sep == AVDT_TSEP_SNK) {
          /* suspend failed, reset back tx flush state */
          btif_a2dp_source_set_tx_flush(false);
        }
        return false;
      }

      if (p_av->suspend.initiator != true) {
        /* remote suspend, notify HAL and await audioflinger to
           suspend/stop stream */

        /* set remote suspend flag to block media task from restarting
           stream only if we did not already initiate a local suspend */
        if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
          btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;

        btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND,
                                &(btif_av_cb.peer_bda));
      } else {
        btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED,
                                &(btif_av_cb.peer_bda));
      }

      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);

      /* suspend completed and state changed, clear pending status */
      btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
      break;

    case BTA_AV_STOP_EVT:
      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event),
                         btif_av_cb.flags);

      btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
      btif_a2dp_on_stopped(&p_av->suspend);

      btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));

      /* if stop was successful, change state to open */
      if (p_av->suspend.status == BTA_AV_SUCCESS)
        btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);

      break;

    case BTA_AV_CLOSE_EVT:
      BTIF_TRACE_WARNING("%s: event=%s flags=0x%x", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event),
                         btif_av_cb.flags);

      btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;

      /* avdtp link is closed */
      btif_a2dp_on_stopped(NULL);

      /* inform the application that we are disconnected */
      btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                   &(btif_av_cb.peer_bda));

      btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
      break;

    case BTIF_AV_OFFLOAD_START_REQ_EVT:
      BTA_AvOffloadStart(btif_av_cb.bta_handle);
      break;

    case BTA_AV_OFFLOAD_START_RSP_EVT:
      btif_a2dp_on_offload_started(p_av->status);
      break;

      CHECK_RC_EVENT(event, (tBTA_AV*)p_data);

    default:
      BTIF_TRACE_WARNING("%s: unhandled event=%s", __func__,
                         dump_av_sm_event_name((btif_av_sm_event_t)event));
      return false;
  }

  return true;
}

/*****************************************************************************
 *  Local event handlers
 *****************************************************************************/

static void btif_av_handle_event(uint16_t event, char* p_param) {
  BTIF_TRACE_EVENT("%s: event=%s", __func__,
                   dump_av_sm_event_name((btif_av_sm_event_t)event));
  switch (event) {
    case BTIF_AV_CLEANUP_REQ_EVT:
      btif_a2dp_source_shutdown();
      btif_a2dp_sink_shutdown();
      break;

    case BTA_AV_REGISTER_EVT:
      if (btif_av_cb.sm_handle == NULL) {
        btif_av_cb.bta_handle = ((tBTA_AV*)p_param)->registr.hndl;
        BTIF_TRACE_DEBUG("%s: BTA AV Handle updated", __func__);
      }
    /* FALLTHROUGH */
    default:
      btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
      btif_av_event_free_data(event, p_param);
  }
}

void btif_av_event_deep_copy(uint16_t event, char* p_dest, char* p_src) {
  BTIF_TRACE_DEBUG("%s", __func__);
  tBTA_AV* av_src = (tBTA_AV*)p_src;
  tBTA_AV* av_dest = (tBTA_AV*)p_dest;

  // First copy the structure
  maybe_non_aligned_memcpy(av_dest, av_src, sizeof(*av_src));
  switch (event) {
    case BTA_AV_META_MSG_EVT:
      if (av_src->meta_msg.p_data && av_src->meta_msg.len) {
        av_dest->meta_msg.p_data = (uint8_t*)osi_calloc(av_src->meta_msg.len);
        memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data,
               av_src->meta_msg.len);
      }

      if (av_src->meta_msg.p_msg) {
        av_dest->meta_msg.p_msg = (tAVRC_MSG*)osi_calloc(sizeof(tAVRC_MSG));
        memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg,
               sizeof(tAVRC_MSG));

        tAVRC_MSG* p_msg_src = av_src->meta_msg.p_msg;
        tAVRC_MSG* p_msg_dest = av_dest->meta_msg.p_msg;

        if ((p_msg_src->hdr.opcode == AVRC_OP_VENDOR) &&
            (p_msg_src->vendor.p_vendor_data && p_msg_src->vendor.vendor_len)) {
          p_msg_dest->vendor.p_vendor_data =
              (uint8_t*)osi_calloc(p_msg_src->vendor.vendor_len);
          memcpy(p_msg_dest->vendor.p_vendor_data,
                 p_msg_src->vendor.p_vendor_data, p_msg_src->vendor.vendor_len);
        }
        if ((p_msg_src->hdr.opcode == AVRC_OP_BROWSE) &&
            p_msg_src->browse.p_browse_data && p_msg_src->browse.browse_len) {
          p_msg_dest->browse.p_browse_data =
              (uint8_t*)osi_calloc(p_msg_src->browse.browse_len);
          memcpy(p_msg_dest->browse.p_browse_data,
                 p_msg_src->browse.p_browse_data, p_msg_src->browse.browse_len);
          android_errorWriteLog(0x534e4554, "109699112");
        }
      }
      break;

    default:
      break;
  }
}

static void btif_av_event_free_data(btif_sm_event_t event, void* p_data) {
  switch (event) {
    case BTA_AV_META_MSG_EVT: {
      tBTA_AV* av = (tBTA_AV*)p_data;
      osi_free_and_reset((void**)&av->meta_msg.p_data);

      if (av->meta_msg.p_msg) {
        if (av->meta_msg.p_msg->hdr.opcode == AVRC_OP_VENDOR) {
          osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
        }
        if (av->meta_msg.p_msg->hdr.opcode == AVRC_OP_BROWSE) {
          osi_free(av->meta_msg.p_msg->browse.p_browse_data);
        }
        osi_free_and_reset((void**)&av->meta_msg.p_msg);
      }
    } break;

    default:
      break;
  }
}

static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV* p_data) {
  btif_transfer_context(btif_av_handle_event, event, (char*)p_data,
                        sizeof(tBTA_AV), btif_av_event_deep_copy);
}

static void bte_av_sink_media_callback(tBTA_AV_EVT event,
                                       tBTA_AV_MEDIA* p_data) {
  switch (event) {
    case BTA_AV_SINK_MEDIA_DATA_EVT: {
      btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
      if ((state == BTIF_AV_STATE_STARTED) || (state == BTIF_AV_STATE_OPENED)) {
        uint8_t queue_len = btif_a2dp_sink_enqueue_buf((BT_HDR*)p_data);
        BTIF_TRACE_DEBUG("%s: packets in sink queue %d", __func__, queue_len);
      }
      break;
    }
    case BTA_AV_SINK_MEDIA_CFG_EVT: {
      btif_av_sink_config_req_t config_req;

      /* send a command to BT Media Task */
      btif_a2dp_sink_update_decoder((uint8_t*)(p_data->avk_config.codec_info));
      /* Switch to BTIF context */
      config_req.sample_rate =
          A2DP_GetTrackSampleRate(p_data->avk_config.codec_info);
      if (config_req.sample_rate == -1) {
        APPL_TRACE_ERROR("%s: cannot get the track frequency", __func__);
        break;
      }
      config_req.channel_count =
          A2DP_GetTrackChannelCount(p_data->avk_config.codec_info);
      if (config_req.channel_count == -1) {
        APPL_TRACE_ERROR("%s: cannot get the channel count", __func__);
        break;
      }

      config_req.peer_bd = p_data->avk_config.bd_addr;
      btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
                            (char*)&config_req, sizeof(config_req), NULL);
      break;
    }
    default:
      break;
  }
}

/*******************************************************************************
 *
 * Function         btif_av_init
 *
 * Description      Initializes btif AV if not already done
 *
 * Returns          bt_status_t
 *
 ******************************************************************************/

bt_status_t btif_av_init(int service_id) {
  if (btif_av_cb.sm_handle == NULL) {
    alarm_free(av_open_on_rc_timer);
    av_open_on_rc_timer = alarm_new("btif_av.av_open_on_rc_timer");

    switch (service_id) {
      case BTA_A2DP_SOURCE_SERVICE_ID:
        if (!btif_a2dp_source_startup())
          return BT_STATUS_FAIL;  // Already running
        break;
      case BTA_A2DP_SINK_SERVICE_ID:
        if (!btif_a2dp_sink_startup())
          return BT_STATUS_FAIL;  // Already running
        break;
      default:
        break;
    }

    btif_enable_service(service_id);

    /* Also initialize the AV state machine */
    btif_av_cb.sm_handle = btif_sm_init(
        (const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
  }

  return BT_STATUS_SUCCESS;
}

/*******************************************************************************
 *
 * Function         init_src
 *
 * Description      Initializes the AV interface for source mode
 *
 * Returns          bt_status_t
 *
 ******************************************************************************/

static bt_status_t init_src(
    btav_source_callbacks_t* callbacks,
    std::vector<btav_a2dp_codec_config_t> codec_priorities) {
  BTIF_TRACE_EVENT("%s", __func__);

  btif_av_cb.codec_priorities = codec_priorities;
  bt_status_t status = btif_av_init(BTA_A2DP_SOURCE_SERVICE_ID);
  if (status == BT_STATUS_SUCCESS) bt_av_src_callbacks = callbacks;

  return status;
}

/*******************************************************************************
 *
 * Function         init_sink
 *
 * Description      Initializes the AV interface for sink mode
 *
 * Returns          bt_status_t
 *
 ******************************************************************************/

static bt_status_t init_sink(btav_sink_callbacks_t* callbacks) {
  BTIF_TRACE_EVENT("%s", __func__);

  bt_status_t status = btif_av_init(BTA_A2DP_SINK_SERVICE_ID);
  if (status == BT_STATUS_SUCCESS) bt_av_sink_callbacks = callbacks;

  return status;
}

/*******************************************************************************
 *
 * Function         update_audio_focus_state
 *
 * Description      Updates the final focus state reported by components calling
 *                  this module.
 *
 * Returns          None
 *
 ******************************************************************************/
static void update_audio_focus_state(int state) {
  BTIF_TRACE_DEBUG("%s: state=%d", __func__, state);
  btif_a2dp_sink_set_focus_state_req((btif_a2dp_sink_focus_state_t)state);
}

/*******************************************************************************
 *
 * Function         update_audio_track_gain
 *
 * Description      Updates the track gain (used for ducking).
 *
 * Returns          None
 *
 ******************************************************************************/
static void update_audio_track_gain(float gain) {
  BTIF_TRACE_DEBUG("%s: gain=%f", __func__, gain);
  btif_a2dp_sink_set_audio_track_gain(gain);
}

/*******************************************************************************
 *
 * Function         connect
 *
 * Description      Establishes the AV signalling channel with the remote
 *                  headset
 *
 * Returns          bt_status_t
 *
 ******************************************************************************/

static bt_status_t connect_int(RawAddress* bd_addr, uint16_t uuid) {
  btif_av_connect_req_t connect_req;
  connect_req.target_bda = bd_addr;
  connect_req.uuid = uuid;
  BTIF_TRACE_EVENT("%s", __func__);

  btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT,
                   (char*)&connect_req);

  return BT_STATUS_SUCCESS;
}

static bt_status_t src_connect_sink(RawAddress* bd_addr) {
  BTIF_TRACE_EVENT("%s", __func__);
  CHECK_BTAV_INIT();

  return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
}

static bt_status_t sink_connect_src(RawAddress* bd_addr) {
  BTIF_TRACE_EVENT("%s", __func__);
  CHECK_BTAV_INIT();

  return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
}

/*******************************************************************************
 *
 * Function         disconnect
 *
 * Description      Tears down the AV signalling channel with the remote headset
 *
 * Returns          bt_status_t
 *
 ******************************************************************************/
static bt_status_t disconnect(RawAddress* bd_addr) {
  BTIF_TRACE_EVENT("%s", __func__);
  CHECK_BTAV_INIT();

  /* Switch to BTIF context */
  return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
                               (char*)bd_addr, sizeof(RawAddress), NULL);
}

static bt_status_t codec_config_src(
    std::vector<btav_a2dp_codec_config_t> codec_preferences) {
  BTIF_TRACE_EVENT("%s", __func__);
  CHECK_BTAV_INIT();

  for (auto cp : codec_preferences) {
    BTIF_TRACE_DEBUG(
        "%s: codec_type=%d codec_priority=%d "
        "sample_rate=0x%x bits_per_sample=0x%x "
        "channel_mode=0x%x codec_specific_1=%d "
        "codec_specific_2=%d codec_specific_3=%d "
        "codec_specific_4=%d",
        __func__, cp.codec_type, cp.codec_priority, cp.sample_rate,
        cp.bits_per_sample, cp.channel_mode, cp.codec_specific_1,
        cp.codec_specific_2, cp.codec_specific_3, cp.codec_specific_4);
    btif_transfer_context(btif_av_handle_event, BTIF_AV_SOURCE_CONFIG_REQ_EVT,
                          reinterpret_cast<char*>(&cp), sizeof(cp), NULL);
  }

  return BT_STATUS_SUCCESS;
}

/*******************************************************************************
 *
 * Function         cleanup
 *
 * Description      Shuts down the AV interface and does the cleanup
 *
 * Returns          None
 *
 ******************************************************************************/
static void cleanup(int service_uuid) {
  BTIF_TRACE_EVENT("%s", __func__);

  btif_transfer_context(btif_av_handle_event, BTIF_AV_CLEANUP_REQ_EVT, NULL, 0,
                        NULL);

  btif_disable_service(service_uuid);

  alarm_free(av_open_on_rc_timer);
  av_open_on_rc_timer = NULL;

  /* Also shut down the AV state machine */
  btif_sm_shutdown(btif_av_cb.sm_handle);
  btif_av_cb.sm_handle = NULL;
}

static void cleanup_src(void) {
  BTIF_TRACE_EVENT("%s", __func__);

  btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SOURCE);
  if (bt_av_src_callbacks) {
    bt_av_src_callbacks = NULL;
    if (bt_av_sink_callbacks == NULL) cleanup(BTA_A2DP_SOURCE_SERVICE_ID);
  }
}

static void cleanup_sink(void) {
  BTIF_TRACE_EVENT("%s", __func__);

  btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SINK);
  if (bt_av_sink_callbacks) {
    bt_av_sink_callbacks = NULL;
    if (bt_av_src_callbacks == NULL) cleanup(BTA_A2DP_SINK_SERVICE_ID);
  }
}

static const btav_source_interface_t bt_av_src_interface = {
    sizeof(btav_source_interface_t),
    init_src,
    src_connect_sink,
    disconnect,
    codec_config_src,
    cleanup_src,
};

static const btav_sink_interface_t bt_av_sink_interface = {
    sizeof(btav_sink_interface_t),
    init_sink,
    sink_connect_src,
    disconnect,
    cleanup_sink,
    update_audio_focus_state,
    update_audio_track_gain,
};

/*******************************************************************************
 *
 * Function         btif_av_get_addr
 *
 * Description      Fetches current AV BD address
 *
 * Returns          BD address
 *
 ******************************************************************************/

RawAddress btif_av_get_addr(void) { return btif_av_cb.peer_bda; }

/*******************************************************************************
 * Function         btif_av_is_sink_enabled
 *
 * Description      Checks if A2DP Sink is enabled or not
 *
 * Returns          true if A2DP Sink is enabled, false otherwise
 *
 ******************************************************************************/

bool btif_av_is_sink_enabled(void) {
  return (bt_av_sink_callbacks != NULL) ? true : false;
}

/*******************************************************************************
 *
 * Function         btif_av_stream_ready
 *
 * Description      Checks whether AV is ready for starting a stream
 *
 * Returns          None
 *
 ******************************************************************************/

bool btif_av_stream_ready(void) {
  btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);

  BTIF_TRACE_DEBUG("%s: sm_handle=%d, state=%d, flags=0x%x", __func__,
                   btif_av_cb.sm_handle, state, btif_av_cb.flags);

  /* also make sure main adapter is enabled */
  if (btif_is_enabled() == 0) {
    BTIF_TRACE_EVENT("%s: main adapter not enabled", __func__);
    return false;
  }

  /* check if we are remotely suspended or stop is pending */
  if (btif_av_cb.flags &
      (BTIF_AV_FLAG_REMOTE_SUSPEND | BTIF_AV_FLAG_PENDING_STOP))
    return false;

  return (state == BTIF_AV_STATE_OPENED);
}

/*******************************************************************************
 *
 * Function         btif_av_stream_started_ready
 *
 * Description      Checks whether AV ready for media start in streaming state
 *
 * Returns          None
 *
 ******************************************************************************/

bool btif_av_stream_started_ready(void) {
  btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
  bool ready = false;

  /* disallow media task to start if we have pending actions */
  if (btif_av_cb.flags &
      (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND |
       BTIF_AV_FLAG_PENDING_STOP)) {
    ready = false;
  } else {
    ready = (state == BTIF_AV_STATE_STARTED);
  }

  BTIF_TRACE_WARNING("%s: sm_handle=%d state=%d flags=0x%x ready=%d", __func__,
                     btif_av_cb.sm_handle, state, btif_av_cb.flags, ready);

  return ready;
}

/*******************************************************************************
 *
 * Function         btif_dispatch_sm_event
 *
 * Description      Send event to AV statemachine
 *
 * Returns          None
 *
 ******************************************************************************/

/* used to pass events to AV statemachine from other tasks */
void btif_dispatch_sm_event(btif_av_sm_event_t event, void* p_data, int len) {
  /* Switch to BTIF context */
  btif_transfer_context(btif_av_handle_event, event, (char*)p_data, len, NULL);
}

/*******************************************************************************
 *
 * Function         btif_av_execute_service
 *
 * Description      Initializes/Shuts down the service
 *
 * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
 *
 ******************************************************************************/
bt_status_t btif_av_execute_service(bool b_enable) {
  if (b_enable) {
/* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
 * handle this request in order to allow incoming connections to succeed.
 * We need to put this back once support for this is added */

/* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
 * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
 * be initiated by the app/audioflinger layers */
/* Support for browsing for SDP record should work only if we enable BROWSE
 * while registering. */
#if (AVRC_METADATA_INCLUDED == TRUE)
    BTA_AvEnable(BTA_SEC_AUTHENTICATE,
                 BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
                     BTA_AV_FEAT_NO_SCO_SSPD
#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
                     | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL |
                     BTA_AV_FEAT_BROWSE
#endif
                 ,
                 bte_av_callback);
#else
    BTA_AvEnable(BTA_SEC_AUTHENTICATE,
                 (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD), bte_av_callback);
#endif
    BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, NULL,
                   UUID_SERVCLASS_AUDIO_SOURCE);
  } else {
    BTA_AvDeregister(btif_av_cb.bta_handle);
    BTA_AvDisable();
  }
  return BT_STATUS_SUCCESS;
}

/*******************************************************************************
 *
 * Function         btif_av_sink_execute_service
 *
 * Description      Initializes/Shuts down the service
 *
 * Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
 *
 ******************************************************************************/
bt_status_t btif_av_sink_execute_service(bool b_enable) {
  if (b_enable) {
    /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
     * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
     * be initiated by the app/audioflinger layers */
    BTA_AvEnable(BTA_SEC_AUTHENTICATE,
                 BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_RCCT |
                     BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
                     BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCTG |
                     BTA_AV_FEAT_BROWSE,
                 bte_av_callback);
    BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AVK_SERVICE_NAME, 0,
                   bte_av_sink_media_callback, UUID_SERVCLASS_AUDIO_SINK);
  } else {
    BTA_AvDeregister(btif_av_cb.bta_handle);
    BTA_AvDisable();
  }
  return BT_STATUS_SUCCESS;
}

/*******************************************************************************
 *
 * Function         btif_av_get_src_interface
 *
 * Description      Get the AV callback interface for A2DP source profile
 *
 * Returns          btav_source_interface_t
 *
 ******************************************************************************/
const btav_source_interface_t* btif_av_get_src_interface(void) {
  BTIF_TRACE_EVENT("%s", __func__);
  return &bt_av_src_interface;
}

/*******************************************************************************
 *
 * Function         btif_av_get_sink_interface
 *
 * Description      Get the AV callback interface for A2DP sink profile
 *
 * Returns          btav_sink_interface_t
 *
 ******************************************************************************/
const btav_sink_interface_t* btif_av_get_sink_interface(void) {
  BTIF_TRACE_EVENT("%s", __func__);
  return &bt_av_sink_interface;
}

/*******************************************************************************
 *
 * Function         btif_av_is_connected
 *
 * Description      Checks if av has a connected sink
 *
 * Returns          bool
 *
 ******************************************************************************/
bool btif_av_is_connected(void) {
  btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
  return ((state == BTIF_AV_STATE_OPENED) || (state == BTIF_AV_STATE_STARTED));
}

uint8_t btif_av_get_peer_sep(void) { return btif_av_cb.peer_sep; }

/*******************************************************************************
 *
 * Function         btif_av_is_peer_edr
 *
 * Description      Check if the connected a2dp device supports
 *                  EDR or not. Only when connected this function
 *                  will accurately provide a true capability of
 *                  remote peer. If not connected it will always be false.
 *
 * Returns          true if remote device is capable of EDR
 *
 ******************************************************************************/
bool btif_av_is_peer_edr(void) {
  ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);

  if (btif_av_cb.edr)
    return true;
  else
    return false;
}

/******************************************************************************
 *
 * Function        btif_av_clear_remote_suspend_flag
 *
 * Description     Clears btif_av_cd.flags if BTIF_AV_FLAG_REMOTE_SUSPEND is set
 *
 * Returns          void
 *****************************************************************************/
void btif_av_clear_remote_suspend_flag(void) {
  BTIF_TRACE_DEBUG("%s: flags=0x%x", __func__, btif_av_cb.flags);
  btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
}

/*******************************************************************************
 *
 * Function         btif_av_peer_supports_3mbps
 *
 * Description      Check if the connected A2DP device supports
 *                  3 Mbps EDR. This function only works if connected.
 *                  If not connected it will always be false.
 *
 * Returns          true if remote device is EDR and supports 3 Mbps
 *
 ******************************************************************************/
bool btif_av_peer_supports_3mbps(void) {
  bool is3mbps = ((btif_av_cb.edr & BTA_AV_EDR_3MBPS) != 0);
  BTIF_TRACE_DEBUG("%s: connected %d, edr_3mbps %d", __func__,
                   btif_av_is_connected(), is3mbps);
  return (btif_av_is_connected() && is3mbps);
}

/*******************************************************************************
 *
 * Function         btif_av_move_idle
 *
 * Description      Opening state is intermediate state. It cannot handle
 *                  incoming/outgoing connect/disconnect requests.When ACL
 *                  is disconnected and we are in opening state then move back
 *                  to idle state which is proper to handle connections.
 *
 * Returns          Void
 *
 ******************************************************************************/
void btif_av_move_idle(RawAddress bd_addr) {
  /* inform the application that ACL is disconnected and move to idle state */
  btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
  BTIF_TRACE_WARNING("%s: ACL Disconnected state %d bd_addr=%s peer_bda=%s",
                     __func__, state, bd_addr.ToString().c_str(),
                     btif_av_cb.peer_bda.ToString().c_str());

  if (state == BTIF_AV_STATE_OPENING && (bd_addr == btif_av_cb.peer_bda)) {
    BTIF_TRACE_DEBUG(
        "%s: Moving State from Opening to Idle due to ACL disconnect",
        __func__);
    btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
                                 &(btif_av_cb.peer_bda));
    btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
  }
}
