summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2009-02-04 09:39:57 -0800
committerJohan Hedberg <johan.hedberg@nokia.com>2009-02-04 09:39:57 -0800
commit8569aed5570e415a2d4361c521c0b511684e3b7e (patch)
tree878d2839e2c280dc4e4fd06a1f108ca43514c3f8 /audio
parent584fe1b71eca9a98b5a0a75e08aaa4fafc4e8d83 (diff)
Delay AVRCP connection when remote device connects A2DP
The audio profile coexistence whitepaper recommends that the initiator of the A2DP connection also initiates the AVRCP connection. This patch adds a two second delay before we attempt connecting AVRCP after the remote device has connected A2DP to us.
Diffstat (limited to 'audio')
-rw-r--r--audio/avdtp.c8
-rw-r--r--audio/control.c4
-rw-r--r--audio/device.c39
-rw-r--r--audio/device.h5
4 files changed, 53 insertions, 3 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c
index a45b7d28..4c95fa49 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -891,8 +891,10 @@ static void connection_lost(struct avdtp *session, int err)
dev = manager_find_device(&session->dst, AUDIO_CONTROL_INTERFACE,
FALSE);
- if (dev)
+ if (dev && dev->control) {
+ device_remove_control_timer(dev);
avrcp_disconnect(dev);
+ }
if (session->state == AVDTP_SESSION_STATE_CONNECTED) {
char address[18];
@@ -2984,8 +2986,8 @@ static void auth_cb(DBusError *derr, void *user_data)
dev = manager_find_device(&session->dst, AUDIO_CONTROL_INTERFACE,
FALSE);
- if (dev)
- avrcp_connect(dev);
+ if (dev && dev->control)
+ device_set_control_timer(dev);
g_source_remove(session->io);
diff --git a/audio/control.c b/audio/control.c
index 1a3e17b4..5cf68cdf 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -691,6 +691,8 @@ static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,
if (!dev->control)
dev->control = control_init(dev);
+ device_remove_control_timer(dev);
+
session->state = AVCTP_STATE_CONNECTING;
session->sock = g_io_channel_unix_get_fd(chan);
@@ -820,6 +822,8 @@ gboolean avrcp_connect(struct audio_device *dev)
return FALSE;
}
+ device_remove_control_timer(dev);
+
session->dev = dev;
session->state = AVCTP_STATE_CONNECTING;
diff --git a/audio/device.c b/audio/device.c
index 6f59746d..a5cfc880 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -54,15 +54,54 @@
#include "headset.h"
#include "sink.h"
+#define CONTROL_CONNECT_TIMEOUT 2
+
static void device_free(struct audio_device *dev)
{
if (dev->conn)
dbus_connection_unref(dev->conn);
+ if (dev->control_timer)
+ g_source_remove(dev->control_timer);
+
g_free(dev->path);
g_free(dev);
}
+static gboolean control_connect_timeout(gpointer user_data)
+{
+ struct audio_device *dev = user_data;
+
+ dev->control_timer = 0;
+
+ if (dev->control)
+ avrcp_connect(dev);
+
+ return FALSE;
+}
+
+gboolean device_set_control_timer(struct audio_device *dev)
+{
+ if (!dev->control)
+ return FALSE;
+
+ if (dev->control_timer)
+ return FALSE;
+
+ dev->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
+ control_connect_timeout,
+ dev);
+
+ return TRUE;
+}
+
+void device_remove_control_timer(struct audio_device *dev)
+{
+ if (dev->control_timer)
+ g_source_remove(dev->control_timer);
+ dev->control_timer = 0;
+}
+
struct audio_device *audio_device_register(DBusConnection *conn,
const char *path, const bdaddr_t *src,
const bdaddr_t *dst)
diff --git a/audio/device.h b/audio/device.h
index 2f626a54..cf27f5ee 100644
--- a/audio/device.h
+++ b/audio/device.h
@@ -63,8 +63,13 @@ struct audio_device {
struct source *source;
struct control *control;
struct target *target;
+
+ guint control_timer;
};
+gboolean device_set_control_timer(struct audio_device *dev);
+void device_remove_control_timer(struct audio_device *dev);
+
struct audio_device *audio_device_register(DBusConnection *conn,
const char *path, const bdaddr_t *src,
const bdaddr_t *dst);