static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *dev = data; struct dev_priv *priv = dev->priv; if (priv->state == AUDIO_STATE_DISCONNECTED) return g_dbus_create_error(msg, ERROR_INTERFACE ".NotConnected", "Not connected"); if (priv->dc_req) return dbus_message_new_method_return(msg); priv->dc_req = dbus_message_ref(msg); if (dev->control) { device_remove_control_timer(dev); avrcp_disconnect(dev); } if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED) sink_shutdown(dev->sink); else if (priv->hs_state != HEADSET_STATE_DISCONNECTED) headset_shutdown(dev); else { dbus_message_unref(priv->dc_req); priv->dc_req = NULL; return dbus_message_new_method_return(msg); } return NULL; }
static void disconnect_cb(struct btd_device *btd_dev, gboolean removal, void *user_data) { struct audio_device *dev = user_data; struct dev_priv *priv = dev->priv; if (priv->state == AUDIO_STATE_DISCONNECTED) return; if (priv->disconnecting) return; priv->disconnecting = TRUE; device_remove_control_timer(dev); device_remove_avdtp_timer(dev); device_remove_headset_timer(dev); if (dev->control) avrcp_disconnect(dev); if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED) sink_shutdown(dev->sink); else if (priv->hs_state != HEADSET_STATE_DISCONNECTED) headset_shutdown(dev); else priv->disconnecting = FALSE; }
static void device_headset_cb(struct audio_device *dev, headset_state_t old_state, headset_state_t new_state, void *user_data) { struct dev_priv *priv = dev->priv; if (!dev->headset) return; priv->hs_state = new_state; switch (new_state) { case HEADSET_STATE_DISCONNECTED: device_remove_avdtp_timer(dev); if (priv->sink_state != SINK_STATE_DISCONNECTED && dev->sink && priv->dc_req) { sink_shutdown(dev->sink); break; } if (priv->sink_state == SINK_STATE_DISCONNECTED) device_set_state(dev, AUDIO_STATE_DISCONNECTED); else if (old_state == HEADSET_STATE_CONNECTING && (priv->sink_state == SINK_STATE_CONNECTED || priv->sink_state == SINK_STATE_PLAYING)) device_set_state(dev, AUDIO_STATE_CONNECTED); break; case HEADSET_STATE_CONNECTING: device_remove_headset_timer(dev); if (priv->sink_state == SINK_STATE_DISCONNECTED) device_set_state(dev, AUDIO_STATE_CONNECTING); break; case HEADSET_STATE_CONNECTED: if (old_state == HEADSET_STATE_CONNECTED || old_state == HEADSET_STATE_PLAY_IN_PROGRESS || old_state == HEADSET_STATE_PLAYING) break; if (dev->auto_connect) { if (!dev->sink) device_set_state(dev, AUDIO_STATE_CONNECTED); else if (priv->sink_state == SINK_STATE_DISCONNECTED) device_set_avdtp_timer(dev); else if (priv->sink_state == SINK_STATE_CONNECTED || priv->sink_state == SINK_STATE_PLAYING) device_set_state(dev, AUDIO_STATE_CONNECTED); } else if (priv->sink_state == SINK_STATE_DISCONNECTED || priv->sink_state == SINK_STATE_CONNECTING) device_set_state(dev, AUDIO_STATE_CONNECTED); break; case HEADSET_STATE_PLAY_IN_PROGRESS: break; case HEADSET_STATE_PLAYING: break; } }