From 43b0855abdf408c8309c3870ad8365475214d3db Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 7 Nov 2016 14:49:38 +0200 Subject: [PATCH] audio/player: Report PlayItem errors Wait for the response of PlayItem and forward and in case of not being successful reply with an error. --- profiles/audio/avrcp.c | 37 ++++++++++++++++++++++++++++++++++++- profiles/audio/player.c | 31 +++++++++++++++++++++++++++++-- profiles/audio/player.h | 1 + 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index 51a89b126..a96fb935e 100644 --- a/profiles/audio/avrcp.c +++ b/profiles/audio/avrcp.c @@ -75,6 +75,8 @@ #define AVRCP_STATUS_PARAM_NOT_FOUND 0x02 #define AVRCP_STATUS_INTERNAL_ERROR 0x03 #define AVRCP_STATUS_SUCCESS 0x04 +#define AVRCP_STATUS_UID_CHANGED 0x05 +#define AVRCP_STATUS_DOES_NOT_EXIST 0x09 #define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b #define AVRCP_STATUS_INVALID_PLAYER_ID 0x11 #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12 @@ -3098,6 +3100,39 @@ static int ct_search(struct media_player *mp, const char *string, return 0; } +static gboolean avrcp_play_item_rsp(struct avctp *conn, uint8_t code, + uint8_t subunit, uint8_t transaction, + uint8_t *operands, size_t operand_count, + void *user_data) +{ + struct avrcp_browsing_header *pdu = (void *) operands; + struct avrcp *session = (void *) user_data; + struct avrcp_player *player = session->controller->player; + struct media_player *mp = player->user_data; + int ret = 0; + + if (pdu == NULL) { + ret = -ETIMEDOUT; + goto done; + } + + if (pdu->params[0] != AVRCP_STATUS_SUCCESS) { + switch (pdu->params[0]) { + case AVRCP_STATUS_UID_CHANGED: + case AVRCP_STATUS_DOES_NOT_EXIST: + ret = -ENOENT; + default: + ret = -EINVAL; + } + goto done; + } + +done: + media_player_play_item_complete(mp, ret); + + return FALSE; +} + static void avrcp_play_item(struct avrcp *session, uint64_t uid) { uint8_t buf[AVRCP_HEADER_LENGTH + 11]; @@ -3120,7 +3155,7 @@ static void avrcp_play_item(struct avrcp *session, uint64_t uid) avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL, buf, length, - NULL, session); + avrcp_play_item_rsp, session); } static int ct_play_item(struct media_player *mp, const char *name, diff --git a/profiles/audio/player.c b/profiles/audio/player.c index 7944b493e..72ebdfa6e 100644 --- a/profiles/audio/player.c +++ b/profiles/audio/player.c @@ -1482,6 +1482,7 @@ static DBusMessage *media_item_play(DBusConnection *conn, DBusMessage *msg, { struct media_item *item = data; struct media_player *mp = item->player; + struct media_folder *folder = mp->scope; struct player_callback *cb = mp->cb; const char *path; int err; @@ -1489,13 +1490,18 @@ static DBusMessage *media_item_play(DBusConnection *conn, DBusMessage *msg, if (!item->playable || !cb->cbs->play_item) return btd_error_not_supported(msg); - path = mp->search && mp->scope == mp->search ? "/Search" : item->path; + if (folder->msg) + return btd_error_failed(msg, strerror(EBUSY)); + + path = mp->search && folder == mp->search ? "/Search" : item->path; err = cb->cbs->play_item(mp, path, item->uid, cb->user_data); if (err < 0) return btd_error_failed(msg, strerror(-err)); - return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + folder->msg = dbus_message_ref(msg); + + return NULL; } static DBusMessage *media_item_add_to_nowplaying(DBusConnection *conn, @@ -1700,6 +1706,27 @@ static const GDBusPropertyTable media_item_properties[] = { { } }; +void media_player_play_item_complete(struct media_player *mp, int err) +{ + struct media_folder *folder = mp->scope; + DBusMessage *reply; + + if (folder == NULL || folder->msg == NULL) + return; + + if (err < 0) { + reply = btd_error_failed(folder->msg, strerror(-err)); + goto done; + } + + reply = g_dbus_create_reply(folder->msg, DBUS_TYPE_INVALID); + +done: + g_dbus_send_message(btd_get_dbus_connection(), reply); + dbus_message_unref(folder->msg); + folder->msg = NULL; +} + void media_item_set_playable(struct media_item *item, bool value) { if (item->playable == value) diff --git a/profiles/audio/player.h b/profiles/audio/player.h index 54e395a13..a7c7d2a0d 100644 --- a/profiles/audio/player.h +++ b/profiles/audio/player.h @@ -102,6 +102,7 @@ struct media_item *media_player_create_item(struct media_player *mp, player_item_type_t type, uint64_t uid); +void media_player_play_item_complete(struct media_player *mp, int err); void media_item_set_playable(struct media_item *item, bool value); void media_player_list_complete(struct media_player *mp, GSList *items, int err); -- 2.47.3