summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-02-19 09:20:42 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2008-02-19 09:20:42 +0000
commitff7353d5c40698a036bcc1e87cd26f2bb3ff3b87 (patch)
tree6ac9237230501ab42a761d5521aadfed26bf4209
parentb3f285d83c7dfe446bd7f2460e6f795e22a72d32 (diff)
Implement basic headset automatic disconnect support
-rw-r--r--audio/headset.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/audio/headset.c b/audio/headset.c
index a42b5131..f507bfb9 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -113,6 +113,8 @@ struct headset {
GIOChannel *sco;
guint sco_id;
+ gboolean auto_dc;
+
guint ring_timer;
char buf[BUF_SIZE];
@@ -1281,6 +1283,8 @@ static DBusHandlerResult hs_connect(DBusConnection *conn, DBusMessage *msg,
if (err < 0)
return error_connection_attempt_failed(conn, msg, -err);
+ hs->auto_dc = FALSE;
+
hs->pending->msg = dbus_message_ref(msg);
return DBUS_HANDLER_RESULT_HANDLED;
@@ -1937,10 +1941,8 @@ gboolean headset_cancel_stream(struct device *dev, unsigned int id)
pending_connect_finalize(dev);
- /* FIXME: disconnecting is not correct for all scenarios, e.g. if the
- * stream request came when we were already connected then we should
- * stay connected after canceling the request too */
- headset_set_state(dev, HEADSET_STATE_DISCONNECTED);
+ if (hs->auto_dc)
+ headset_set_state(dev, HEADSET_STATE_DISCONNECTED);
return TRUE;
}
@@ -1956,7 +1958,6 @@ unsigned int headset_request_stream(struct device *dev, headset_stream_cb_t cb,
{
struct headset *hs = dev->headset;
unsigned int id;
- int err;
if (hs->rfcomm && hs->sco) {
id = connect_cb_new(hs, HEADSET_STATE_PLAYING, cb, user_data);
@@ -1964,21 +1965,21 @@ unsigned int headset_request_stream(struct device *dev, headset_stream_cb_t cb,
return id;
}
- if (hs->rfcomm == NULL)
- err = rfcomm_connect(dev, cb, user_data, &id);
- else if (hs->sco == NULL)
- err = sco_connect(dev, cb, user_data, &id);
+ if (hs->state == HEADSET_STATE_CONNECT_IN_PROGRESS)
+ return connect_cb_new(hs, HEADSET_STATE_PLAYING, cb, user_data);
- if (err < 0)
- goto error;
+ if (hs->rfcomm == NULL) {
+ if (rfcomm_connect(dev, cb, user_data, &id) < 0)
+ return 0;
+ hs->auto_dc = TRUE;
+ } else {
+ if (sco_connect(dev, cb, user_data, &id) < 0)
+ return 0;
+ }
hs->pending->target_state = HEADSET_STATE_PLAYING;
return id;
-
-error:
- pending_connect_finalize(dev);
- return 0;
}
gboolean get_hfp_active(struct device *dev)
@@ -2038,6 +2039,8 @@ void headset_set_authorized(struct device *dev)
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
(GIOFunc) rfcomm_io_cb, dev);
+ hs->auto_dc = FALSE;
+
if (!hs->hfp_active)
headset_set_state(dev, HEADSET_STATE_CONNECTED);
}
@@ -2142,8 +2145,13 @@ gboolean headset_unlock(struct device *dev, headset_lock_t lock)
hs->lock &= ~lock;
- if (!hs->lock && hs->state > HEADSET_STATE_DISCONNECTED)
+ if (hs->lock)
+ return TRUE;
+
+ if (hs->auto_dc)
headset_set_state(dev, HEADSET_STATE_DISCONNECTED);
+ else if (hs->state == HEADSET_STATE_PLAYING)
+ headset_set_state(dev, HEADSET_STATE_CONNECTED);
return TRUE;
}