Fix authorization when the audio profiles are slow to connect

Incoming audio connections should be automatically authorized if either
HFP/HSP or A2DP is already connected for the same device.
diff --git a/audio/avdtp.c b/audio/avdtp.c
index 71a8da2..0ee81c0 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -1028,6 +1028,8 @@
 	if (session->ref == 1) {
 		if (session->state == AVDTP_SESSION_STATE_CONNECTING &&
 								session->io) {
+			btd_cancel_authorization(&session->server->src,
+							&session->dst);
 			g_io_channel_shutdown(session->io, TRUE, NULL);
 			g_io_channel_unref(session->io);
 			session->io = NULL;
@@ -2136,6 +2138,7 @@
 
 	session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 					(GIOFunc) session_cb, session);
+
 	perr = audio_device_request_authorization(dev, ADVANCED_AUDIO_UUID,
 							auth_cb, session);
 	if (perr < 0) {
diff --git a/audio/control.c b/audio/control.c
index e49c229..d7161c0 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -710,12 +710,8 @@
 	avctp_set_state(control, AVCTP_STATE_CONNECTING);
 	control->io = g_io_channel_ref(chan);
 
-	if (avdtp_is_connected(&src, &dst)) {
-		if (!bt_io_accept(chan, avctp_connect_cb, dev->control,
-								NULL, NULL))
-			goto drop;
-	} else if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
-			auth_cb, dev->control) < 0)
+	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
+						auth_cb, dev->control) < 0)
 		goto drop;
 
 	return;
diff --git a/audio/device.c b/audio/device.c
index 85a6a78..27d2bdb 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -683,6 +683,42 @@
 	}
 }
 
+static gboolean auth_idle_cb(gpointer user_data)
+{
+	auth_cb(NULL, user_data);
+	return FALSE;
+}
+
+static gboolean audio_device_is_connected(struct audio_device *dev)
+{
+	if (dev->headset) {
+		headset_state_t state = headset_get_state(dev);
+
+		if (state == HEADSET_STATE_CONNECTED ||
+				state == HEADSET_STATE_PLAY_IN_PROGRESS ||
+				state == HEADSET_STATE_PLAYING)
+			return TRUE;
+	}
+
+	if (dev->sink) {
+		sink_state_t state = sink_get_state(dev);
+
+		if (state == SINK_STATE_CONNECTED ||
+				state == SINK_STATE_PLAYING)
+			return TRUE;
+	}
+
+	if (dev->source) {
+		source_state_t state = source_get_state(dev);
+
+		if (state == SOURCE_STATE_CONNECTED ||
+				state == SOURCE_STATE_PLAYING)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 int audio_device_request_authorization(struct audio_device *dev,
 					const char *uuid, service_auth_cb cb,
 					void *user_data)
@@ -702,6 +738,11 @@
 	if (g_slist_length(priv->auths) > 1)
 		return 0;
 
+	if (audio_device_is_connected(dev)) {
+		g_idle_add(auth_idle_cb, dev);
+		return 0;
+	}
+
 	err = btd_request_authorization(&dev->src, &dev->dst, uuid, auth_cb,
 					dev);
 	if (err < 0) {