From: Mikel Astiz <mikel.astiz.oss@gmail.com>
To: linux-bluetooth@vger.kernel.org
Cc: Mikel Astiz <mikel.astiz@bmw-carit.de>
Subject: [RFC v5 1/4] media: Split transport state based on playing flag
Date: Fri, 14 Sep 2012 14:55:57 +0200 [thread overview]
Message-ID: <1347627360-13997-2-git-send-email-mikel.astiz.oss@gmail.com> (raw)
In-Reply-To: <1347627360-13997-1-git-send-email-mikel.astiz.oss@gmail.com>
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Split the transport states (formerly in_use) into more specific states
where the stream state (playing or suspended) is explicitly represented,
along with the transitional states (locally initiated suspend and
resume).
TRANSPORT_STATE_ACTIVE is an exception since it also includes the state
where the transport is acquired, but the audio was later suspended (not
released yet though).
---
audio/transport.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 57 insertions(+), 11 deletions(-)
diff --git a/audio/transport.c b/audio/transport.c
index 3026022..e0402ad 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -57,13 +57,19 @@ typedef enum {
} transport_lock_t;
typedef enum {
- TRANSPORT_STATE_IDLE, /* Not acquired */
- TRANSPORT_STATE_ACQUIRED, /* Acquired (not necessarily playing) */
+ TRANSPORT_STATE_IDLE, /* Not acquired and suspended */
+ TRANSPORT_STATE_PENDING, /* Playing but not acquired */
+ TRANSPORT_STATE_REQUESTING, /* Acquire in progress */
+ TRANSPORT_STATE_ACTIVE, /* Acquired (not necessarily playing) */
+ TRANSPORT_STATE_SUSPENDING, /* Release in progress */
} transport_state_t;
static char *str_state[] = {
"TRANSPORT_STATE_IDLE",
- "TRANSPORT_STATE_ACQUIRED",
+ "TRANSPORT_STATE_PENDING",
+ "TRANSPORT_STATE_REQUESTING",
+ "TRANSPORT_STATE_ACTIVE",
+ "TRANSPORT_STATE_SUSPENDING",
};
struct media_request {
@@ -153,8 +159,11 @@ static gboolean state_in_use(transport_state_t state)
{
switch (state) {
case TRANSPORT_STATE_IDLE:
+ case TRANSPORT_STATE_PENDING:
return FALSE;
- case TRANSPORT_STATE_ACQUIRED:
+ case TRANSPORT_STATE_REQUESTING:
+ case TRANSPORT_STATE_ACTIVE:
+ case TRANSPORT_STATE_SUSPENDING:
return TRUE;
}
@@ -356,6 +365,8 @@ static void a2dp_resume_complete(struct avdtp *session,
media_owner_remove(owner);
+ transport_set_state(transport, TRANSPORT_STATE_ACTIVE);
+
return;
fail:
@@ -382,7 +393,8 @@ static guint resume_a2dp(struct media_transport *transport,
if (a2dp_sep_lock(sep, a2dp->session) == FALSE)
return 0;
- transport_set_state(transport, TRANSPORT_STATE_ACQUIRED);
+ if (transport->state == TRANSPORT_STATE_IDLE)
+ transport_set_state(transport, TRANSPORT_STATE_REQUESTING);
done:
return a2dp_resume(a2dp->session, sep, a2dp_resume_complete, owner);
@@ -417,7 +429,12 @@ static guint suspend_a2dp(struct media_transport *transport,
if (!owner) {
a2dp_sep_unlock(sep, a2dp->session);
- transport_set_state(transport, TRANSPORT_STATE_IDLE);
+
+ if (a2dp_sep_is_playing(sep))
+ transport_set_state(transport, TRANSPORT_STATE_PENDING);
+ else
+ transport_set_state(transport, TRANSPORT_STATE_IDLE);
+
return 0;
}
@@ -468,6 +485,8 @@ static void headset_resume_complete(struct audio_device *dev, void *user_data)
media_owner_remove(owner);
+ transport_set_state(transport, TRANSPORT_STATE_ACTIVE);
+
return;
fail:
@@ -486,7 +505,8 @@ static guint resume_headset(struct media_transport *transport,
HEADSET_LOCK_WRITE) == FALSE)
return 0;
- transport_set_state(transport, TRANSPORT_STATE_ACQUIRED);
+ if (transport->state == TRANSPORT_STATE_IDLE)
+ transport_set_state(transport, TRANSPORT_STATE_REQUESTING);
done:
return headset_request_stream(device, headset_resume_complete,
@@ -516,8 +536,15 @@ static guint suspend_headset(struct media_transport *transport,
struct audio_device *device = transport->device;
if (!owner) {
+ headset_state_t state = headset_get_state(device);
+
headset_unlock(device, HEADSET_LOCK_READ | HEADSET_LOCK_WRITE);
- transport_set_state(transport, TRANSPORT_STATE_IDLE);
+
+ if (state == HEADSET_STATE_PLAYING)
+ transport_set_state(transport, TRANSPORT_STATE_PENDING);
+ else
+ transport_set_state(transport, TRANSPORT_STATE_IDLE);
+
return 0;
}
@@ -574,6 +601,8 @@ static void gateway_resume_complete(struct audio_device *dev, GError *err,
media_owner_remove(owner);
+ transport_set_state(transport, TRANSPORT_STATE_ACTIVE);
+
return;
fail:
@@ -592,7 +621,8 @@ static guint resume_gateway(struct media_transport *transport,
GATEWAY_LOCK_WRITE) == FALSE)
return 0;
- transport_set_state(transport, TRANSPORT_STATE_ACQUIRED);
+ if (transport->state == TRANSPORT_STATE_IDLE)
+ transport_set_state(transport, TRANSPORT_STATE_REQUESTING);
done:
return gateway_request_stream(device, gateway_resume_complete,
@@ -625,8 +655,15 @@ static guint suspend_gateway(struct media_transport *transport,
static int id = 1;
if (!owner) {
+ gateway_state_t state = gateway_get_state(device);
+
gateway_unlock(device, GATEWAY_LOCK_READ | GATEWAY_LOCK_WRITE);
- transport_set_state(transport, TRANSPORT_STATE_IDLE);
+
+ if (state == GATEWAY_STATE_PLAYING)
+ transport_set_state(transport, TRANSPORT_STATE_PENDING);
+ else
+ transport_set_state(transport, TRANSPORT_STATE_IDLE);
+
return 0;
}
@@ -806,6 +843,8 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
return btd_error_in_progress(msg);
}
+ transport_set_state(transport, TRANSPORT_STATE_SUSPENDING);
+
id = transport->suspend(transport, owner);
if (id == 0) {
media_transport_remove(transport, owner);
@@ -1104,7 +1143,14 @@ static void headset_nrec_changed(struct audio_device *dev, gboolean nrec,
static void transport_update_playing(struct media_transport *transport,
gboolean playing)
{
- DBG("%s Playing=%d", transport->path, playing);
+ DBG("%s State=%s Playing=%d", transport->path,
+ str_state[transport->state], playing);
+
+ if (playing == FALSE) {
+ if (transport->state == TRANSPORT_STATE_PENDING)
+ transport_set_state(transport, TRANSPORT_STATE_IDLE);
+ } else if (transport->state == TRANSPORT_STATE_IDLE)
+ transport_set_state(transport, TRANSPORT_STATE_PENDING);
}
static void headset_state_changed(struct audio_device *dev,
--
1.7.7.6
next prev parent reply other threads:[~2012-09-14 12:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-14 12:55 [RFC v5 0/4] Optional acquire in Media API and related Mikel Astiz
2012-09-14 12:55 ` Mikel Astiz [this message]
2012-09-14 12:55 ` [RFC v5 2/4] media: Expose transport state in D-Bus Mikel Astiz
2012-09-14 12:55 ` [RFC v5 3/4] media: Automatically release transport when HUP Mikel Astiz
2012-09-14 12:56 ` [RFC v5 4/4] media: Extend media API with optional acquire Mikel Astiz
2012-09-17 13:33 ` [RFC v5 0/4] Optional acquire in Media API and related Luiz Augusto von Dentz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1347627360-13997-2-git-send-email-mikel.astiz.oss@gmail.com \
--to=mikel.astiz.oss@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=mikel.astiz@bmw-carit.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox