All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/5 v2] AVRCP: Prefix folder name with /Filesystem
@ 2013-02-06  9:14 Luiz Augusto von Dentz
  2013-02-06  9:14 ` [PATCH BlueZ 2/5 v2] AVRCP: Parse browsing and searching features bits Luiz Augusto von Dentz
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-02-06  9:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This separate the scopes of the folder as documented in doc/media-api.txt
---
 profiles/audio/avrcp.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 00eeea1..5967180 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1935,9 +1935,10 @@ static gboolean avrcp_set_browsed_player_rsp(struct avctp *conn,
 
 	depth = operands[13];
 
-	folders = g_new0(char *, depth + 1);
+	folders = g_new0(char *, depth + 2);
+	folders[0] = g_strdup("/Filesystem");
 
-	for (i = 14, count = 0; count < depth; count++) {
+	for (i = 14, count = 1; count - 1 < depth; count++) {
 		char *part;
 		uint8_t len;
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 2/5 v2] AVRCP: Parse browsing and searching features bits
  2013-02-06  9:14 [PATCH BlueZ 1/5 v2] AVRCP: Prefix folder name with /Filesystem Luiz Augusto von Dentz
@ 2013-02-06  9:14 ` Luiz Augusto von Dentz
  2013-02-06  9:14 ` [PATCH BlueZ 3/5 v2] media-api: Fix referencing to MediaLibrary instead of MediaFolder Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-02-06  9:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This parses browsing and searching features bits and set the respective
property.
---
v2: Check if folder is available to enable Browsable and Searchable properties

 profiles/audio/avrcp.c  | 18 +++++++++----
 profiles/audio/player.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++-
 profiles/audio/player.h |  2 ++
 3 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 5967180..cabe2ee 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1976,6 +1976,18 @@ static void avrcp_set_browsed_player(struct avrcp *session,
 				avrcp_set_browsed_player_rsp, session);
 }
 
+static void avrcp_player_parse_features(struct avrcp_player *player,
+							uint8_t *features)
+{
+	struct media_player *mp = player->user_data;
+
+	if (features[7] & 0x08)
+		media_player_set_browsable(mp, true);
+
+	if (features[7] & 0x10)
+		media_player_set_searchable(mp, true);
+}
+
 static void avrcp_parse_media_player_item(struct avrcp *session,
 					uint8_t *operands, uint16_t len)
 {
@@ -1984,7 +1996,6 @@ static void avrcp_parse_media_player_item(struct avrcp *session,
 	uint16_t id;
 	uint32_t subtype;
 	const char *curval, *strval;
-	uint64_t features[2];
 	char name[255];
 
 	if (len < 28)
@@ -2009,10 +2020,7 @@ static void avrcp_parse_media_player_item(struct avrcp *session,
 		avrcp_get_play_status(session);
 	}
 
-	features[0] = bt_get_be64(&operands[8]);
-	features[1] = bt_get_be64(&operands[16]);
-
-	media_player_set_features(mp, features);
+	avrcp_player_parse_features(player, &operands[8]);
 
 	if (operands[26] != 0) {
 		memcpy(name, &operands[27], operands[26]);
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index f875ee7..019ed1f 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -67,7 +67,9 @@ struct media_player {
 	char			*name;		/* Player name */
 	char			*type;		/* Player type */
 	char			*subtype;	/* Player subtype */
-	uint64_t		features[2];	/* Player features */
+	bool			browsable;	/* Player browsing feature */
+	bool			searchable;	/* Player searching feature */
+	uint8_t			*features;	/* Player features */
 	struct media_folder	*folder;	/* Player currenct folder */
 	char			*path;		/* Player object path */
 	GHashTable		*settings;	/* Player settings */
@@ -350,6 +352,53 @@ static gboolean get_subtype(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean browsable_exists(const GDBusPropertyTable *property, void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->folder != NULL;
+}
+
+static gboolean get_browsable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+
+	if (mp->folder == NULL)
+		return FALSE;
+
+	DBG("%s", mp->browsable ? "true" : "false");
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+							&mp->browsable);
+
+	return TRUE;
+}
+
+static gboolean searchable_exists(const GDBusPropertyTable *property,
+								void *data)
+{
+	struct media_player *mp = data;
+
+	return mp->folder != NULL;
+}
+
+static gboolean get_searchable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_player *mp = data;
+
+	if (mp->folder == NULL)
+		return FALSE;
+
+	DBG("%s", mp->searchable ? "true" : "false");
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+							&mp->searchable);
+
+	return TRUE;
+}
+
 static DBusMessage *media_player_play(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -510,6 +559,10 @@ static const GDBusPropertyTable media_player_properties[] = {
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ "Device", "s", get_device, NULL, NULL,
 					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Browsable", "b", get_browsable, NULL, browsable_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Searchable", "b", get_searchable, NULL, searchable_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
 	{ }
 };
 
@@ -659,6 +712,8 @@ struct media_player *media_player_controller_create(const char *path)
 	mp->track = g_hash_table_new_full(g_str_hash, g_str_equal,
 							g_free, g_free);
 	mp->progress = g_timer_new();
+	mp->browsable = -1;
+	mp->searchable = -1;
 
 	if (!g_dbus_register_interface(btd_get_dbus_connection(),
 					mp->path, MEDIA_PLAYER_INTERFACE,
@@ -843,6 +898,20 @@ void media_player_set_name(struct media_player *mp, const char *name)
 					"Name");
 }
 
+void media_player_set_browsable(struct media_player *mp, bool enabled)
+{
+	DBG("%s", enabled ? "true" : "false");
+
+	mp->browsable = enabled;
+}
+
+void media_player_set_searchable(struct media_player *mp, bool enabled)
+{
+	DBG("%s", enabled ? "true" : "false");
+
+	mp->searchable = enabled;
+}
+
 void media_player_set_folder(struct media_player *mp, const char *path,
 								uint32_t items)
 {
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 1ac9800..e9a7d1c 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -51,6 +51,8 @@ void media_player_set_type(struct media_player *mp, const char *type);
 void media_player_set_subtype(struct media_player *mp, const char *subtype);
 void media_player_set_features(struct media_player *mp, uint64_t *features);
 void media_player_set_name(struct media_player *mp, const char *name);
+void media_player_set_browsable(struct media_player *mp, bool enabled);
+void media_player_set_searchable(struct media_player *mp, bool enabled);
 void media_player_set_folder(struct media_player *mp, const char *path,
 								uint32_t items);
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 3/5 v2] media-api: Fix referencing to MediaLibrary instead of MediaFolder
  2013-02-06  9:14 [PATCH BlueZ 1/5 v2] AVRCP: Prefix folder name with /Filesystem Luiz Augusto von Dentz
  2013-02-06  9:14 ` [PATCH BlueZ 2/5 v2] AVRCP: Parse browsing and searching features bits Luiz Augusto von Dentz
@ 2013-02-06  9:14 ` Luiz Augusto von Dentz
  2013-02-06  9:14 ` [PATCH BlueZ 4/5 v2] AVRCP: Move features to avrcp.c Luiz Augusto von Dentz
  2013-02-06  9:15 ` [PATCH BlueZ 5/5 v2] AVRCP: Create folders for /Filesystem and /NowPlaying Luiz Augusto von Dentz
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-02-06  9:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

MediaLibrary was replaced by MediaFolder so doesn't exist anymore.
---
 doc/media-api.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/media-api.txt b/doc/media-api.txt
index db1575f..2656a9e 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -233,7 +233,7 @@ Properties	string Equalizer [readwrite]
 		boolean Browsable [readonly]
 
 			If present indicates the player can be browsed using
-			MediaLibrary interface.
+			MediaFolder interface.
 
 			Possible values:
 
@@ -248,7 +248,7 @@ Properties	string Equalizer [readwrite]
 		boolean Searchable [readonly]
 
 			If present indicates the player can be searched using
-			MediaLibrary interface.
+			MediaFolder interface.
 
 			Possible values:
 
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 4/5 v2] AVRCP: Move features to avrcp.c
  2013-02-06  9:14 [PATCH BlueZ 1/5 v2] AVRCP: Prefix folder name with /Filesystem Luiz Augusto von Dentz
  2013-02-06  9:14 ` [PATCH BlueZ 2/5 v2] AVRCP: Parse browsing and searching features bits Luiz Augusto von Dentz
  2013-02-06  9:14 ` [PATCH BlueZ 3/5 v2] media-api: Fix referencing to MediaLibrary instead of MediaFolder Luiz Augusto von Dentz
@ 2013-02-06  9:14 ` Luiz Augusto von Dentz
  2013-02-06  9:15 ` [PATCH BlueZ 5/5 v2] AVRCP: Create folders for /Filesystem and /NowPlaying Luiz Augusto von Dentz
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-02-06  9:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

avrcp.c should be responsible for specifics of AVRCP not player.c which
is more high level abstraction.
---
 profiles/audio/avrcp.c  | 4 ++++
 profiles/audio/player.c | 8 --------
 profiles/audio/player.h | 1 -
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index cabe2ee..55887bc 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -180,6 +180,7 @@ struct avrcp_player {
 	GSList *sessions;
 	uint16_t id;
 	uint16_t uid_counter;
+	uint8_t *features;
 
 	struct avrcp_player_cb *cb;
 	void *user_data;
@@ -1981,6 +1982,8 @@ static void avrcp_player_parse_features(struct avrcp_player *player,
 {
 	struct media_player *mp = player->user_data;
 
+	player->features = g_memdup(features, 16);
+
 	if (features[7] & 0x08)
 		media_player_set_browsable(mp, true);
 
@@ -2553,6 +2556,7 @@ static void player_destroy(gpointer data)
 		player->destroy(player->user_data);
 
 	g_slist_free(player->sessions);
+	g_free(player->features);
 	g_free(player);
 }
 
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 019ed1f..558aee5 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -69,7 +69,6 @@ struct media_player {
 	char			*subtype;	/* Player subtype */
 	bool			browsable;	/* Player browsing feature */
 	bool			searchable;	/* Player searching feature */
-	uint8_t			*features;	/* Player features */
 	struct media_folder	*folder;	/* Player currenct folder */
 	char			*path;		/* Player object path */
 	GHashTable		*settings;	/* Player settings */
@@ -939,13 +938,6 @@ void media_player_set_folder(struct media_player *mp, const char *path,
 	}
 }
 
-void media_player_set_features(struct media_player *mp, uint64_t *features)
-{
-	DBG("0x%016" PRIx64 "%016" PRIx64, features[0], features[1]);
-
-	memcpy(features, mp->features, sizeof(mp->features));
-}
-
 void media_player_set_callbacks(struct media_player *mp,
 				const struct media_player_callback *cbs,
 				void *user_data)
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index e9a7d1c..9109b1f 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -49,7 +49,6 @@ void media_player_set_metadata(struct media_player *mp, const char *key,
 						void *data, size_t len);
 void media_player_set_type(struct media_player *mp, const char *type);
 void media_player_set_subtype(struct media_player *mp, const char *subtype);
-void media_player_set_features(struct media_player *mp, uint64_t *features);
 void media_player_set_name(struct media_player *mp, const char *name);
 void media_player_set_browsable(struct media_player *mp, bool enabled);
 void media_player_set_searchable(struct media_player *mp, bool enabled);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 5/5 v2] AVRCP: Create folders for /Filesystem and /NowPlaying
  2013-02-06  9:14 [PATCH BlueZ 1/5 v2] AVRCP: Prefix folder name with /Filesystem Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2013-02-06  9:14 ` [PATCH BlueZ 4/5 v2] AVRCP: Move features to avrcp.c Luiz Augusto von Dentz
@ 2013-02-06  9:15 ` Luiz Augusto von Dentz
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-02-06  9:15 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If browsing is supported create objects representing /Filesystem and
/NowPlaying, these object implement MediaItem interface and can be
passed to ChangeFolder to change the scope.
---
 profiles/audio/avrcp.c  |   7 +-
 profiles/audio/player.c | 232 ++++++++++++++++++++++++++++++++++++++++++------
 profiles/audio/player.h |   2 +
 3 files changed, 215 insertions(+), 26 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 55887bc..3b9aad6 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1984,11 +1984,16 @@ static void avrcp_player_parse_features(struct avrcp_player *player,
 
 	player->features = g_memdup(features, 16);
 
-	if (features[7] & 0x08)
+	if (features[7] & 0x08) {
 		media_player_set_browsable(mp, true);
+		media_player_create_folder(mp, "/Filesystem");
+	}
 
 	if (features[7] & 0x10)
 		media_player_set_searchable(mp, true);
+
+	if (features[8] & 0x02)
+		media_player_create_folder(mp, "/NowPlaying");
 }
 
 static void avrcp_parse_media_player_item(struct avrcp *session,
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index 558aee5..9ff21cf 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -45,6 +45,7 @@
 
 #define MEDIA_PLAYER_INTERFACE "org.bluez.MediaPlayer1"
 #define MEDIA_FOLDER_INTERFACE "org.bluez.MediaFolder1"
+#define MEDIA_ITEM_INTERFACE "org.bluez.MediaItem1"
 
 struct player_callback {
 	const struct media_player_callback *cbs;
@@ -57,9 +58,17 @@ struct pending_req {
 	const char *value;
 };
 
+struct media_item {
+	struct media_player	*player;
+	char			*path;		/* Item object path */
+	char			*name;		/* Item name */
+	bool			folder;		/* Item folder flag */
+	bool			playable;	/* Item playable flag */
+};
+
 struct media_folder {
-	char			*name;		/* Folder name */
-	uint32_t		items;		/* Number of items */
+	struct media_item	*item;		/* Folder item */
+	uint32_t		number_of_items;/* Number of items */
 };
 
 struct media_player {
@@ -79,6 +88,7 @@ struct media_player {
 	guint			process_id;
 	struct player_callback	*cb;
 	GSList			*pending;
+	GSList			*folders;
 };
 
 static void append_metadata(void *key, void *value, void *user_data)
@@ -588,25 +598,27 @@ static gboolean folder_name_exists(const GDBusPropertyTable *property,
 								void *data)
 {
 	struct media_player *mp = data;
+	struct media_folder *folder = mp->folder;
 
-	if (mp->folder == NULL)
+	if (folder == NULL || folder->item == NULL)
 		return FALSE;
 
-	return mp->folder->name != NULL;
+	return folder->item->name != NULL;
 }
 
 static gboolean get_folder_name(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
 	struct media_player *mp = data;
+	struct media_folder *folder = mp->folder;
 
-	if (mp->folder == NULL || mp->folder->name == NULL)
+	if (folder == NULL || folder->item == NULL)
 		return FALSE;
 
-	DBG("%s", mp->folder->name);
+	DBG("%s", folder->item->name);
 
 	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
-							&mp->folder->name);
+							&folder->item->name);
 
 	return TRUE;
 }
@@ -622,14 +634,15 @@ static gboolean get_items(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
 	struct media_player *mp = data;
+	struct media_folder *folder = mp->folder;
 
-	if (mp->folder == NULL)
+	if (folder == NULL)
 		return FALSE;
 
-	DBG("%u", mp->folder->items);
+	DBG("%u", folder->number_of_items);
 
 	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
-							&mp->folder->items);
+						&folder->number_of_items);
 
 	return TRUE;
 }
@@ -657,9 +670,22 @@ static const GDBusPropertyTable media_folder_properties[] = {
 	{ }
 };
 
+static void media_item_destroy(void *data)
+{
+	struct media_item *item = data;
+
+	DBG("%s", item->path);
+
+	g_dbus_unregister_interface(btd_get_dbus_connection(), item->path,
+						MEDIA_ITEM_INTERFACE);
+
+	g_free(item->path);
+	g_free(item->name);
+	g_free(item);
+}
+
 static void media_folder_destroy(struct media_folder *folder)
 {
-	g_free(folder->name);
 	g_free(folder);
 }
 
@@ -687,6 +713,7 @@ void media_player_destroy(struct media_player *mp)
 	}
 
 	g_slist_free_full(mp->pending, g_free);
+	g_slist_free_full(mp->folders, media_item_destroy);
 
 	g_timer_destroy(mp->progress);
 	g_free(mp->cb);
@@ -911,31 +938,186 @@ void media_player_set_searchable(struct media_player *mp, bool enabled)
 	mp->searchable = enabled;
 }
 
-void media_player_set_folder(struct media_player *mp, const char *path,
-								uint32_t items)
+static void media_player_set_folder_item(struct media_player *mp,
+						struct media_item *item,
+						uint32_t number_of_items)
 {
 	struct media_folder *folder;
 
-	DBG("%s items %u", path, items);
+	folder = mp->folder;
 
-	if (mp->folder != NULL)
-		media_folder_destroy(mp->folder);
-
-	folder = g_new0(struct media_folder, 1);
-	folder->name = g_strdup(path);
-	folder->items = items;
-	mp->folder = folder;
+	if (folder == NULL) {
+		folder = g_new0(struct media_folder, 1);
+		mp->folder = folder;
 
-	if (!g_dbus_register_interface(btd_get_dbus_connection(),
+		if (!g_dbus_register_interface(btd_get_dbus_connection(),
 					mp->path, MEDIA_FOLDER_INTERFACE,
 					media_folder_methods,
 					NULL,
 					media_folder_properties, mp, NULL)) {
-		error("D-Bus failed to register %s on %s path",
+			error("D-Bus failed to register %s on %s path",
 					MEDIA_FOLDER_INTERFACE, mp->path);
-		media_folder_destroy(mp->folder);
-		mp->folder = NULL;
+			media_folder_destroy(mp->folder);
+			mp->folder = NULL;
+		}
+	}
+
+	folder->item = item;
+	folder->number_of_items = number_of_items;
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+				MEDIA_FOLDER_INTERFACE, "Name");
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), mp->path,
+				MEDIA_FOLDER_INTERFACE, "NumberOfItems");
+}
+
+static struct media_item *media_player_find_folder(struct media_player *mp,
+							const char *name)
+{
+	GSList *l;
+
+	for (l = mp->folders; l; l = l->next) {
+		struct media_item *item = l->data;
+
+		if (!item->folder)
+			continue;
+
+		if (g_str_equal(item->name, name))
+			return item;
+	}
+
+	return NULL;
+}
+
+void media_player_set_folder(struct media_player *mp, const char *name,
+						uint32_t number_of_items)
+{
+	struct media_item *item;
+
+	DBG("%s number of items %u", name, number_of_items);
+
+	item = media_player_find_folder(mp, name);
+	if (item == NULL) {
+		error("Unknown folder: %s", name);
+		return;
+	}
+
+	media_player_set_folder_item(mp, item, number_of_items);
+}
+
+static DBusMessage *media_item_play(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	return btd_error_failed(msg, strerror(ENOTSUP));
+}
+
+static DBusMessage *media_item_add_to_nowplaying(DBusConnection *conn,
+						DBusMessage *msg, void *data)
+{
+	return btd_error_failed(msg, strerror(ENOTSUP));
+}
+
+static gboolean item_name_exists(const GDBusPropertyTable *property,
+								void *data)
+{
+	struct media_item *item = data;
+
+	return item->name != NULL;
+}
+
+static gboolean get_item_name(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_item *item = data;
+
+	if (item->name == NULL)
+		return FALSE;
+
+	DBG("%s", item->name);
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &item->name);
+
+	return TRUE;
+}
+
+static gboolean get_folder_flag(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_item *item = data;
+	dbus_bool_t value;
+
+	DBG("%s", item->folder ? "true" : "false");
+
+	value = item->folder ? TRUE : FALSE;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
+static gboolean get_playable(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct media_item *item = data;
+	dbus_bool_t value;
+
+	DBG("%s", item->playable ? "true" : "false");
+
+	value = item->playable ? TRUE : FALSE;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
+static const GDBusMethodTable media_item_methods[] = {
+	{ GDBUS_EXPERIMENTAL_METHOD("Play", NULL, NULL,
+					media_item_play) },
+	{ GDBUS_EXPERIMENTAL_METHOD("AddtoNowPlaying", NULL, NULL,
+					media_item_add_to_nowplaying) },
+	{ }
+};
+
+static const GDBusPropertyTable media_item_properties[] = {
+	{ "Name", "s", get_item_name, NULL, item_name_exists,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Folder", "b", get_folder_flag, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ "Playable", "b", get_playable, NULL, NULL,
+					G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
+	{ }
+};
+
+int media_player_create_folder(struct media_player *mp, const char *name)
+{
+	struct media_item *item;
+
+	DBG("%s", name);
+
+	item = g_new0(struct media_item, 1);
+	item->player = mp;
+	item->path = g_strdup_printf("%s%s", mp->path, name);
+	item->name = g_strdup(name);
+	item->folder = true;
+	item->playable = false;
+
+	if (!g_dbus_register_interface(btd_get_dbus_connection(),
+					item->path, MEDIA_ITEM_INTERFACE,
+					media_item_methods,
+					NULL,
+					media_item_properties, item, NULL)) {
+		error("D-Bus failed to register %s on %s path",
+					MEDIA_ITEM_INTERFACE, item->path);
+		media_item_destroy(item);
+		return -EINVAL;
 	}
+
+	if (mp->folder == NULL)
+		media_player_set_folder_item(mp, item, 0);
+
+	mp->folders = g_slist_prepend(mp->folders, item);
+
+	return 0;
 }
 
 void media_player_set_callbacks(struct media_player *mp,
diff --git a/profiles/audio/player.h b/profiles/audio/player.h
index 9109b1f..a59cc66 100644
--- a/profiles/audio/player.h
+++ b/profiles/audio/player.h
@@ -55,6 +55,8 @@ void media_player_set_searchable(struct media_player *mp, bool enabled);
 void media_player_set_folder(struct media_player *mp, const char *path,
 								uint32_t items);
 
+int media_player_create_folder(struct media_player *mp, const char *path);
+
 void media_player_set_callbacks(struct media_player *mp,
 				const struct media_player_callback *cbs,
 				void *user_data);
-- 
1.8.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-02-06  9:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-06  9:14 [PATCH BlueZ 1/5 v2] AVRCP: Prefix folder name with /Filesystem Luiz Augusto von Dentz
2013-02-06  9:14 ` [PATCH BlueZ 2/5 v2] AVRCP: Parse browsing and searching features bits Luiz Augusto von Dentz
2013-02-06  9:14 ` [PATCH BlueZ 3/5 v2] media-api: Fix referencing to MediaLibrary instead of MediaFolder Luiz Augusto von Dentz
2013-02-06  9:14 ` [PATCH BlueZ 4/5 v2] AVRCP: Move features to avrcp.c Luiz Augusto von Dentz
2013-02-06  9:15 ` [PATCH BlueZ 5/5 v2] AVRCP: Create folders for /Filesystem and /NowPlaying Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.