[RFC v3 8/9] media: Expose transport state in D-Bus

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx>

Extend the Media API to expose the transport state in D-Bus, as a
property of the transport. This way the clients do not have to find
out which is the corresponding profile-specific interface for the
transport.

Additionally, this state along with the automatic release of transports
will allow clients to avoid the "optional release" or "accept remote
release" race condition. For example, with HSP/HFP profiles, the problem
is the following:

1. User suspends SCO in the remote end.
2. BlueZ signals the Playing->Connected state change in D-Bus.
3. Exactly afterwards, the user resumes SCO in the remote end.
4. In parallel, PulseAudio sees the aforementioned transition to
   Connected, and thus releases the transport.
5. BlueZ receives a Release() request while SCO is up. So the audio
   stream will be suspended.

The last step is an undesired behavior since the user explicitly wanted
to route the audio stream through Bluetooth.

The issue is difficult to reproduce but it can easily be solved by
exposing the transport state in D-Bus.
---
 audio/transport.c |   29 +++++++++++++++++++++++++++++
 doc/media-api.txt |    8 ++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/audio/transport.c b/audio/transport.c
index 79fa38d..05bb953 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -155,6 +155,22 @@ static transport_lock_t str2lock(const char *str)
 	return lock;
 }
 
+static const char *state2str(transport_state_t state)
+{
+	switch (state) {
+	case TRANSPORT_STATE_IDLE:
+	case TRANSPORT_STATE_REQUESTING:
+		return "idle";
+	case TRANSPORT_STATE_PENDING:
+		return "pending";
+	case TRANSPORT_STATE_ACQUIRED:
+	case TRANSPORT_STATE_SUSPENDING:
+		return "acquired";
+	}
+
+	return NULL;
+}
+
 static gboolean state_in_use(transport_state_t state)
 {
 	switch (state) {
@@ -174,6 +190,7 @@ static void transport_set_state(struct media_transport *transport,
 							transport_state_t state)
 {
 	transport_state_t old_state = transport->state;
+	const char *str;
 
 	if (old_state == state)
 		return;
@@ -182,6 +199,13 @@ static void transport_set_state(struct media_transport *transport,
 
 	DBG("State changed %s: %s -> %s", transport->path, str_state[old_state],
 							str_state[state]);
+
+	str = state2str(state);
+
+	if (g_strcmp0(str, state2str(old_state)) != 0)
+		emit_property_changed(transport->conn, transport->path,
+					MEDIA_TRANSPORT_INTERFACE, "State",
+					DBUS_TYPE_STRING, &str);
 }
 
 void media_transport_destroy(struct media_transport *transport)
@@ -1017,6 +1041,7 @@ void transport_get_properties(struct media_transport *transport,
 	DBusMessageIter dict;
 	const char *uuid;
 	uint8_t codec;
+	const char *state;
 
 	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
 			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -1036,6 +1061,10 @@ void transport_get_properties(struct media_transport *transport,
 	dict_append_array(&dict, "Configuration", DBUS_TYPE_BYTE,
 				&transport->configuration, transport->size);
 
+	/* State */
+	state = state2str(transport->state);
+	dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state);
+
 	if (transport->get_properties)
 		transport->get_properties(transport, &dict);
 
diff --git a/doc/media-api.txt b/doc/media-api.txt
index e5eeaa0..dfbff2e 100644
--- a/doc/media-api.txt
+++ b/doc/media-api.txt
@@ -317,6 +317,14 @@ Properties	object Device [readonly]
 			Configuration blob, it is used as it is so the size and
 			byte order must match.
 
+		string State [readonly]
+
+			Indicates the state of the transport. Possible
+			values are:
+				"idle": not streaming
+				"pending": streaming but not acquired
+				"acquired": streaming and acquired
+
 		uint16 Delay [readwrite]
 
 			Optional. Transport delay in 1/10 of millisecond, this
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux