Diff between cc80afff47938a2c93aff0f7904fd937e6333908 and 43b0855abdf408c8309c3870ad8365475214d3db

Changed Files

File Additions Deletions Status
profiles/audio/avrcp.c +36 -1 modified
profiles/audio/player.c +29 -2 modified
profiles/audio/player.h +1 -0 modified

Full Patch

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 51a89b1..a96fb93 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 7944b49..72ebdfa 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 54e395a..a7c7d2a 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);