From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> Refactor the code to use an array of states instead of independent member fields, avoiding duplicated code and improving readability. --- src/modules/bluetooth/bluetooth-util.c | 81 ++++++++++++++----------- src/modules/bluetooth/bluetooth-util.h | 13 +--- src/modules/bluetooth/module-bluetooth-device.c | 59 +++++------------- 3 files changed, 62 insertions(+), 91 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 6f784d1..4986501 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -93,6 +93,24 @@ pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value) { return PA_BT_AUDIO_STATE_INVALID; } +static bool pa_bt_audio_profile_from_interface(const char *interface, enum profile *p) { + if (pa_streq(interface, "org.bluez.AudioSink")) { + *p = PROFILE_A2DP; + return true; + } else if (pa_streq(interface, "org.bluez.AudioSource")) { + *p = PROFILE_A2DP_SOURCE; + return true; + } else if (pa_streq(interface, "org.bluez.Headset")) { + *p = PROFILE_HSP; + return true; + } else if (pa_streq(interface, "org.bluez.HandsfreeGateway")) { + *p = PROFILE_HFGW; + return true; + } + + return false; +} + static pa_bluetooth_uuid *uuid_new(const char *uuid) { pa_bluetooth_uuid *u; @@ -112,6 +130,7 @@ static void uuid_free(pa_bluetooth_uuid *u) { static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const char *path) { pa_bluetooth_device *d; + unsigned i; pa_assert(discovery); pa_assert(path); @@ -133,10 +152,9 @@ static pa_bluetooth_device* device_new(pa_bluetooth_discovery *discovery, const d->trusted = -1; d->audio_state = PA_BT_AUDIO_STATE_INVALID; - d->audio_sink_state = PA_BT_AUDIO_STATE_INVALID; - d->audio_source_state = PA_BT_AUDIO_STATE_INVALID; - d->headset_state = PA_BT_AUDIO_STATE_INVALID; - d->hfgw_state = PA_BT_AUDIO_STATE_INVALID; + + for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++) + d->profile_state[i] = PA_BT_AUDIO_STATE_INVALID; return d; } @@ -185,14 +203,18 @@ static void device_free(pa_bluetooth_device *d) { } static pa_bool_t device_is_audio_ready(const pa_bluetooth_device *d) { + unsigned i; + pa_assert(d); - return - d->device_info_valid && d->audio_state != PA_BT_AUDIO_STATE_INVALID && - (d->audio_sink_state != PA_BT_AUDIO_STATE_INVALID || - d->audio_source_state != PA_BT_AUDIO_STATE_INVALID || - d->headset_state != PA_BT_AUDIO_STATE_INVALID || - d->hfgw_state != PA_BT_AUDIO_STATE_INVALID); + if (!d->device_info_valid || d->audio_state == PA_BT_AUDIO_STATE_INVALID) + return FALSE; + + for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++) + if (d->profile_state[i] != PA_BT_AUDIO_STATE_INVALID) + return TRUE; + + return FALSE; } static const char *check_variant_property(DBusMessageIter *i) { @@ -570,6 +592,7 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) { if (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter dict_i; + enum profile profile; dbus_message_iter_recurse(&element_i, &dict_i); @@ -589,22 +612,13 @@ static void get_properties_reply(DBusPendingCall *pending, void *userdata) { if (parse_audio_property(y, &d->audio_state, &dict_i) < 0) goto finish; - } else if (dbus_message_has_interface(p->message, "org.bluez.Headset")) { - if (parse_audio_property(y, &d->headset_state, &dict_i) < 0) - goto finish; - - } else if (dbus_message_has_interface(p->message, "org.bluez.AudioSink")) { - if (parse_audio_property(y, &d->audio_sink_state, &dict_i) < 0) - goto finish; + } else if (pa_bt_audio_profile_from_interface(dbus_message_get_interface(p->message), &profile)) { + pa_bt_audio_state_t state; - } else if (dbus_message_has_interface(p->message, "org.bluez.AudioSource")) { - if (parse_audio_property(y, &d->audio_source_state, &dict_i) < 0) - goto finish; - - } else if (dbus_message_has_interface(p->message, "org.bluez.HandsfreeGateway")) { - if (parse_audio_property(y, &d->hfgw_state, &dict_i) < 0) + if (parse_audio_property(y, &state, &dict_i) < 0) goto finish; + d->profile_state[profile] = state; } } @@ -846,6 +860,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) { DBusMessageIter arg_i; + enum profile profile; bool old_any_connected = pa_bluetooth_device_any_audio_connected(d); if (!dbus_message_iter_init(m, &arg_i)) { @@ -861,21 +876,13 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if (parse_audio_property(y, &d->audio_state, &arg_i) < 0) goto fail; - } else if (dbus_message_has_interface(m, "org.bluez.Headset")) { - if (parse_audio_property(y, &d->headset_state, &arg_i) < 0) - goto fail; + } else if (pa_bt_audio_profile_from_interface(dbus_message_get_interface(m), &profile)) { + pa_bt_audio_state_t state; - } else if (dbus_message_has_interface(m, "org.bluez.AudioSink")) { - if (parse_audio_property(y, &d->audio_sink_state, &arg_i) < 0) + if (parse_audio_property(y, &state, &arg_i) < 0) goto fail; - } else if (dbus_message_has_interface(m, "org.bluez.AudioSource")) { - if (parse_audio_property(y, &d->audio_source_state, &arg_i) < 0) - goto fail; - - } else if (dbus_message_has_interface(m, "org.bluez.HandsfreeGateway")) { - if (parse_audio_property(y, &d->hfgw_state, &arg_i) < 0) - goto fail; + d->profile_state[profile] = state; } if (old_any_connected != pa_bluetooth_device_any_audio_connected(d)) @@ -989,8 +996,8 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { * loaded. */ return d->audio_state >= PA_BT_AUDIO_STATE_CONNECTED || - d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED || - d->hfgw_state >= PA_BT_AUDIO_STATE_CONNECTED; + d->profile_state[PROFILE_A2DP_SOURCE] >= PA_BT_AUDIO_STATE_CONNECTED || + d->profile_state[PROFILE_HFGW] >= PA_BT_AUDIO_STATE_CONNECTED; } int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu) { diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index ecc663c..35f91df 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -126,17 +126,8 @@ struct pa_bluetooth_device { /* Audio state */ pa_bt_audio_state_t audio_state; - /* AudioSink state */ - pa_bt_audio_state_t audio_sink_state; - - /* AudioSource state */ - pa_bt_audio_state_t audio_source_state; - - /* Headset state */ - pa_bt_audio_state_t headset_state; - - /* HandsfreeGateway state */ - pa_bt_audio_state_t hfgw_state; + /* AudioSink, AudioSource, Headset and HandsfreeGateway states */ + pa_bt_audio_state_t profile_state[PA_BLUETOOTH_PROFILE_COUNT]; }; pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core); diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 649e73f..83b18f3 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -366,23 +366,6 @@ static void bt_transport_release(struct userdata *u) { teardown_stream(u); } -static pa_bt_audio_state_t get_profile_audio_state(const struct userdata *u, const pa_bluetooth_device *d) { - switch(u->profile) { - case PROFILE_HSP: - return d->headset_state; - case PROFILE_A2DP: - return d->audio_sink_state; - case PROFILE_A2DP_SOURCE: - return d->audio_source_state; - case PROFILE_HFGW: - return d->hfgw_state; - case PROFILE_OFF: - break; - } - - pa_assert_not_reached(); -} - static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { const char *accesstype = "rw"; @@ -404,7 +387,7 @@ static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { suspended in the meantime, so we can't really guarantee that the stream will not be requested until BlueZ's API supports this atomically. */ - if (get_profile_audio_state(u, u->device) < PA_BT_AUDIO_STATE_PLAYING) { + if (u->device->profile_state[u->profile] < PA_BT_AUDIO_STATE_PLAYING) { pa_log_info("Failed optional acquire of transport %s", u->transport->path); return -1; } @@ -1368,7 +1351,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if (pa_hashmap_get(u->card->profiles, "a2dp") == NULL) available = audio_state_to_availability(state); else - available = audio_state_to_availability_merged(state, u->device->audio_sink_state); + available = audio_state_to_availability_merged(state, u->device->profile_state[PROFILE_A2DP]); pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-output")); pa_device_port_set_available(port, available); @@ -1402,7 +1385,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if (pa_hashmap_get(u->card->profiles, "hsp") == NULL) available = audio_state_to_availability(state); else - available = audio_state_to_availability_merged(state, u->device->headset_state); + available = audio_state_to_availability_merged(state, u->device->profile_state[PROFILE_HSP]); pa_assert_se(port = pa_hashmap_get(u->card->ports, "bluetooth-output")); pa_device_port_set_available(port, available); @@ -2207,17 +2190,8 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { if (*d != PROFILE_OFF) { const pa_bluetooth_device *device = u->device; - if (device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) { - pa_log_warn("HSP is not connected, refused to switch profile"); - return -PA_ERR_IO; - } else if (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) { - pa_log_warn("A2DP Sink is not connected, refused to switch profile"); - return -PA_ERR_IO; - } else if (device->audio_source_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP_SOURCE) { - pa_log_warn("A2DP Source is not connected, refused to switch profile"); - return -PA_ERR_IO; - } else if (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW) { - pa_log_warn("HandsfreeGateway is not connected, refused to switch profile"); + if (device->profile_state[*d] < PA_BT_AUDIO_STATE_CONNECTED) { + pa_log_warn("Profile not connected, refused to switch profile to %s", new_profile->name); return -PA_ERR_IO; } } @@ -2262,7 +2236,8 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c case PROFILE_A2DP: if ((port = pa_hashmap_get(ports, "bluetooth-output")) != NULL) { port->priority = PA_MAX(port->priority, profile->priority * 100); - port->available = audio_state_to_availability_merged(device->headset_state, device->audio_sink_state); + port->available = audio_state_to_availability_merged(device->profile_state[PROFILE_HSP], + device->profile_state[PROFILE_A2DP]); pa_hashmap_put(port->profiles, profile->name, profile); } else { pa_assert_se(port = pa_device_port_new(u->core, "bluetooth-output", _("Bluetooth Output"), 0)); @@ -2270,7 +2245,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c port->is_output = 1; port->is_input = 0; port->priority = profile->priority * 100; - port->available = audio_state_to_availability(device->audio_sink_state); + port->available = audio_state_to_availability(device->profile_state[*d]); pa_hashmap_put(port->profiles, profile->name, profile); } @@ -2282,14 +2257,15 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c port->is_output = 0; port->is_input = 1; port->priority = profile->priority * 100; - port->available = audio_state_to_availability(device->audio_source_state); + port->available = audio_state_to_availability(device->profile_state[*d]); pa_hashmap_put(port->profiles, profile->name, profile); break; case PROFILE_HSP: if ((port = pa_hashmap_get(ports, "bluetooth-output")) != NULL) { port->priority = PA_MAX(port->priority, profile->priority * 100); - port->available = audio_state_to_availability_merged(device->headset_state, device->audio_sink_state); + port->available = audio_state_to_availability_merged(device->profile_state[PROFILE_HSP], + device->profile_state[PROFILE_A2DP]); pa_hashmap_put(port->profiles, profile->name, profile); } else { pa_assert_se(port = pa_device_port_new(u->core, "bluetooth-output", _("Bluetooth Output"), 0)); @@ -2297,7 +2273,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c port->is_output = 1; port->is_input = 0; port->priority = profile->priority * 100; - port->available = audio_state_to_availability(device->headset_state); + port->available = audio_state_to_availability(device->profile_state[*d]); pa_hashmap_put(port->profiles, profile->name, profile); } @@ -2306,7 +2282,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c port->is_output = 0; port->is_input = 1; port->priority = profile->priority * 100; - port->available = audio_state_to_availability(device->headset_state); + port->available = audio_state_to_availability(device->profile_state[*d]); pa_hashmap_put(port->profiles, profile->name, profile); break; @@ -2316,7 +2292,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c port->is_output = 1; port->is_input = 0; port->priority = profile->priority * 100; - port->available = audio_state_to_availability(device->hfgw_state); + port->available = audio_state_to_availability(device->profile_state[*d]); pa_hashmap_put(port->profiles, profile->name, profile); pa_assert_se(port = pa_device_port_new(u->core, "hfgw-input", _("Bluetooth Handsfree Gateway"), 0)); @@ -2324,7 +2300,7 @@ static void create_ports_for_profile(struct userdata *u, pa_hashmap *ports, pa_c port->is_output = 0; port->is_input = 1; port->priority = profile->priority * 100; - port->available = audio_state_to_availability(device->hfgw_state); + port->available = audio_state_to_availability(device->profile_state[*d]); pa_hashmap_put(port->profiles, profile->name, profile); break; @@ -2466,10 +2442,7 @@ static int add_card(struct userdata *u) { d = PA_CARD_PROFILE_DATA(u->card->active_profile); - if ((device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) || - (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) || - (device->audio_source_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP_SOURCE) || - (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW)) { + if (*d != PROFILE_OFF && (device->profile_state[*d] < PA_BT_AUDIO_STATE_CONNECTED)) { pa_log_warn("Default profile not connected, selecting off profile"); u->card->active_profile = pa_hashmap_get(u->card->profiles, "off"); u->card->save_profile = FALSE; -- 1.7.11.7