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

Commit 9a5f970f authored by Sanket Agarwal's avatar Sanket Agarwal Committed by Pavlin Radoslavov
Browse files

Implement AVRCP Controller (Client) Browsing.

Following is included as part of the features:
a) Browsing for all 4 scopes (Media, VFS, Player and Now Playing)
b) Player selection and song selection from browse list.

The change constructs the following (from lower to upper protocol
layers):
1. AVCTP Browse (bta/ & stack/)
                -- Connection Handling
                -- Constructing browse commands
                -- Parsing browse responses
2. AVRCP  (btif/)
                -- JNI interaction/API
                -- Connection handling to Java
                -- Delegating request and responses to Java

Bug: 28791287
Change-Id: Ibc97ded93cb9c469778ea1e37733390d561cd4cd
(cherry picked from commit 9ea8d07c9286a1f4d338dd64ee02266e324d28e5)
parent ed6c24fe
Loading
Loading
Loading
Loading
+33 −13
Original line number Diff line number Diff line
@@ -535,13 +535,12 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
        return;
    }

    if (p_cb->features & BTA_AV_FEAT_RCTG)
    {
    APPL_TRACE_DEBUG("%s local features %d peer features %d",
                     __func__, p_cb->features, p_cb->rcb[i].peer_features);

    /* listen to browsing channel when the connection is open,
     * if peer initiated AVRCP connection and local device supports browsing channel */
        if ((p_cb->features & BTA_AV_FEAT_BROWSE) && (p_cb->rcb[i].peer_features == 0))
    AVRC_OpenBrowse (p_data->rc_conn_chg.handle, AVCT_ACP);
    }

    if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0)
    {
@@ -588,7 +587,7 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
    bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
    rc_open.peer_features = p_cb->rcb[i].peer_features;
    rc_open.status = BTA_AV_SUCCESS;
    APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features,
    APPL_TRACE_DEBUG("%s local features:x%x peer_features:x%x", __func__, p_cb->features,
                      rc_open.peer_features);
    if (rc_open.peer_features == 0)
    {
@@ -604,14 +603,15 @@ void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
    (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);

    /* if local initiated AVRCP connection and both peer and locals device support
     * browsing channel, open the browsing channel now */
     * browsing channel, open the browsing channel now
     * TODO (sanketa): Some TG would not broadcast browse feature hence check inter-op. */
    if ((p_cb->features & BTA_AV_FEAT_BROWSE) &&
        (rc_open.peer_features & BTA_AV_FEAT_BROWSE) &&
        ((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT))
    {
        APPL_TRACE_DEBUG("%s opening AVRC Browse channel", __func__);
        AVRC_OpenBrowse (p_data->rc_conn_chg.handle, AVCT_INT);
    }

}

/*******************************************************************************
@@ -1141,6 +1141,20 @@ void bta_av_rc_close (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
    }
}

/*******************************************************************************
**
** Function         bta_av_rc_browse_close
**
** Description      Empty placeholder.
**
** Returns          void
**
*******************************************************************************/
void bta_av_rc_browse_close (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
{
    APPL_TRACE_WARNING("%s empty placeholder does nothing!", __func__);
}

/*******************************************************************************
**
** Function         bta_av_get_shdl
@@ -1472,10 +1486,13 @@ void bta_av_disable(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
    /* disable audio/video - de-register all channels,
     * expect BTA_AV_DEREG_COMP_EVT when deregister is complete */
    for(xx=0; xx<BTA_AV_NUM_STRS; xx++)
    {
        if (p_cb->p_scb[xx] != NULL)
        {
            hdr.layer_specific = xx + 1;
            bta_av_api_deregister((tBTA_AV_DATA *)&hdr);
        }
    }

    alarm_free(p_cb->link_signalling_timer);
    p_cb->link_signalling_timer = NULL;
@@ -1855,7 +1872,7 @@ tBTA_AV_FEAT bta_avk_check_peer_features (uint16_t service_uuid)
             */
            if (peer_rc_version >= AVRC_REV_1_3)
            {
                /* get supported categories */
                /* get supported features */
                tSDP_DISC_ATTR *p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FEATURES);
                if (p_attr != NULL)
                {
@@ -1864,6 +1881,8 @@ tBTA_AV_FEAT bta_avk_check_peer_features (uint16_t service_uuid)
                        peer_features |= (BTA_AV_FEAT_ADV_CTRL);
                    if (categories & AVRC_SUPF_CT_APP_SETTINGS)
                        peer_features |= (BTA_AV_FEAT_APP_SETTING);
                    if (categories & AVRC_SUPF_CT_BROWSE)
                        peer_features |= (BTA_AV_FEAT_BROWSE);
                }
            }
        }
@@ -1930,6 +1949,7 @@ void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
    {
        /* This is Sink + CT + TG(Abs Vol) */
        peer_features = bta_avk_check_peer_features(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
        APPL_TRACE_DEBUG("%s populating rem ctrl target features %d", __func__, peer_features);
        if (BTA_AV_FEAT_ADV_CTRL & bta_avk_check_peer_features(UUID_SERVCLASS_AV_REMOTE_CONTROL))
            peer_features |= (BTA_AV_FEAT_ADV_CTRL|BTA_AV_FEAT_RCCT);
    }
+2 −1
Original line number Diff line number Diff line
@@ -124,10 +124,11 @@ const tBTA_AV_CFG bta_av_cfg =
    BTA_AV_RC_COMP_ID,      /* AVRCP Company ID */
#if (AVRC_METADATA_INCLUDED == TRUE)
    512,                    /* AVRCP MTU at L2CAP for control channel */
    BTA_AV_MAX_RC_BR_MTU,   /* AVRCP MTU at L2CAP for browsing channel */
#else
    48,                     /* AVRCP MTU at L2CAP for control channel */
#endif
    BTA_AV_MAX_RC_BR_MTU,   /* AVRCP MTU at L2CAP for browsing channel */
#endif
    BTA_AV_RC_SUPF_CT,      /* AVRCP controller categories */
    BTA_AV_RC_SUPF_TG,      /* AVRCP target categories */
    672,                    /* AVDTP signaling channel MTU at L2CAP */
+38 −24
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ enum
    BTA_AV_RC_META_RSP,
    BTA_AV_RC_MSG,
    BTA_AV_RC_CLOSE,
    BTA_AV_RC_BROWSE_CLOSE,
    BTA_AV_NUM_ACTIONS
};

@@ -103,7 +104,6 @@ const tBTA_AV_ACTION bta_av_action[] =
    bta_av_rc_meta_rsp,
    bta_av_rc_msg,
    bta_av_rc_close,
    NULL
};

/* state table information */
@@ -503,6 +503,12 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
                bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu,
                                (uint8_t)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV);
#endif

                /* Both Audio Source and Audio Sink support AVRCP 1.6 for the
                 * major roles (i.e. Audio Source -> TG 1.6 and vice versa). For
                 * Audio Sink role we support additional TG 1.3 to support
                 * absolute volume. Here we only do TG registration.
                 */
                uint16_t profile_version = AVRC_REV_1_0;
                if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE)
                {
@@ -659,14 +665,21 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
                    /* create an SDP record as AVRC CT. We create 1.3 for SOURCE
                     * because we rely on feature bits being scanned by external
                     * devices more than the profile version itself.
                     *
                     * We create 1.4 for SINK since we support browsing.
                     */
                    if ((profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) ||
                        (profile_initialized == UUID_SERVCLASS_AUDIO_SINK))
                    if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE)
                    {
                        bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL,
                        p_bta_av_cfg->avrc_ct_cat, BTA_ID_AV,
                        (bta_av_cb.features & BTA_AV_FEAT_BROWSE), AVRC_REV_1_3);
                    }
                    else if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK)
                    {
                        bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL,
                        p_bta_av_cfg->avrc_ct_cat, BTA_ID_AV,
                        (bta_av_cb.features & BTA_AV_FEAT_BROWSE), AVRC_REV_1_4);
                    }
#endif
                }
            }
@@ -1191,11 +1204,12 @@ void bta_av_sm_execute(tBTA_AV_CB *p_cb, uint16_t event, tBTA_AV_DATA *p_data)

    /* set next state */
    p_cb->state = state_table[event][BTA_AV_NEXT_STATE];
    APPL_TRACE_EVENT("next state=%d", p_cb->state);
    APPL_TRACE_EVENT("next state=%d event offset:%d", p_cb->state, event);

    /* execute action functions */
    if ((action = state_table[event][BTA_AV_ACTION_COL]) != BTA_AV_IGNORE)
    {
        APPL_TRACE_EVENT("%s action executed %d", __func__, action);
        (*bta_av_action[action])(p_cb, p_data);
    }
}
+29 −31
Original line number Diff line number Diff line
@@ -197,7 +197,6 @@ typedef uint8_t tBTA_AV_CODE;

typedef uint8_t tBTA_AV_ERR;


/* AV callback events */
#define BTA_AV_ENABLE_EVT              0       /* AV enabled */
#define BTA_AV_REGISTER_EVT            1       /* registered to AVDT */
@@ -209,28 +208,27 @@ typedef uint8_t tBTA_AV_ERR;
#define BTA_AV_PROTECT_RSP_EVT         7       /* content protection response */
#define BTA_AV_RC_OPEN_EVT             8       /* remote control channel open */
#define BTA_AV_RC_CLOSE_EVT            9       /* remote control channel closed */
#define BTA_AV_RC_BROWSE_OPEN_EVT    10 /* remote control browse channel open */
#define BTA_AV_RC_BROWSE_CLOSE_EVT   11 /* remote control browse channel closed */
#define BTA_AV_REMOTE_CMD_EVT        12 /* remote control command */
#define BTA_AV_REMOTE_RSP_EVT        13 /* remote control response */
#define BTA_AV_VENDOR_CMD_EVT        14 /* vendor dependent remote control command */
#define BTA_AV_VENDOR_RSP_EVT        15 /* vendor dependent remote control response */
#define BTA_AV_RECONFIG_EVT          16 /* reconfigure response */
#define BTA_AV_SUSPEND_EVT           17 /* suspend response */
#define BTA_AV_PENDING_EVT           18 /* incoming connection pending:
#define BTA_AV_REMOTE_CMD_EVT          10      /* remote control command */
#define BTA_AV_REMOTE_RSP_EVT          11      /* remote control response */
#define BTA_AV_VENDOR_CMD_EVT          12      /* vendor dependent remote control command */
#define BTA_AV_VENDOR_RSP_EVT          13      /* vendor dependent remote control response */
#define BTA_AV_RECONFIG_EVT            14      /* reconfigure response */
#define BTA_AV_SUSPEND_EVT             15      /* suspend response */
#define BTA_AV_PENDING_EVT             16      /* incoming connection pending:
                                                * signal channel is open and stream is
                                                * not open after
                                                * BTA_AV_SIGNALLING_TIMEOUT_MS */
#define BTA_AV_META_MSG_EVT          19 /* metadata messages */
#define BTA_AV_REJECT_EVT            20 /* incoming connection rejected */
#define BTA_AV_RC_FEAT_EVT           21 /* remote control channel peer supported features update */
#define BTA_AV_SINK_MEDIA_CFG_EVT    22 /* command to configure sink codec */
#define BTA_AV_SINK_MEDIA_DATA_EVT   23 /* sending sink data to Media Task */
#define BTA_AV_OFFLOAD_START_RSP_EVT 24 /* a2dp offload start response */
#define BTA_AV_META_MSG_EVT            17      /* metadata messages */
#define BTA_AV_REJECT_EVT              18      /* incoming connection rejected */
#define BTA_AV_RC_FEAT_EVT             19      /* remote control channel peer supported features update */
#define BTA_AV_SINK_MEDIA_CFG_EVT      20      /* command to configure codec */
#define BTA_AV_SINK_MEDIA_DATA_EVT     21      /* sending data to Media Task */
#define BTA_AV_OFFLOAD_START_RSP_EVT   22      /* a2dp offload start response */
#define BTA_AV_RC_BROWSE_OPEN_EVT      23      /* remote control channel open */
#define BTA_AV_RC_BROWSE_CLOSE_EVT     24      /* remote control channel closed */
/* Max BTA event */
#define BTA_AV_MAX_EVT                 25


typedef uint8_t tBTA_AV_EVT;

/* Event associated with BTA_AV_ENABLE_EVT */
+3 −3
Original line number Diff line number Diff line
@@ -116,8 +116,8 @@ else\
/* 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_CLOSE_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: \
@@ -1074,12 +1074,12 @@ static void btif_av_handle_event(uint16_t event, char* 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:
@@ -1594,7 +1594,7 @@ bt_status_t btif_av_sink_execute_service(bool b_enable)
          * 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_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);
Loading