card: Ensure that there's always at least one profile.

In practice there is always at least one profile, and I
don't think there will ever be cards without profiles.
Therefore, I added assertions to pa_card_new() stating that
the card new data must always contain at least one profile.
Now a lot of code can be simplified, because it's guaranteed
that the profiles hashmap and the active_profile field are
always non-NULL.
This commit is contained in:
Tanu Kaskinen 2012-06-08 21:49:10 +03:00
parent 1a6da64b16
commit 12af302ac7
9 changed files with 35 additions and 70 deletions

View file

@ -502,7 +502,6 @@ int pa__init(pa_module *m) {
if ((description = pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION))) if ((description = pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION)))
pa_reserve_wrapper_set_application_device_name(reserve, description); pa_reserve_wrapper_set_application_device_name(reserve, description);
data.profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
add_profiles(u, data.profiles, data.ports); add_profiles(u, data.profiles, data.ports);
if (pa_hashmap_isempty(data.profiles)) { if (pa_hashmap_isempty(data.profiles)) {

View file

@ -2852,8 +2852,6 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
return -1; return -1;
} }
data.profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
/* we base hsp/a2dp availability on UUIDs. /* we base hsp/a2dp availability on UUIDs.
Ideally, it would be based on "Connected" state, but Ideally, it would be based on "Connected" state, but
we can't afford to wait for this information when we can't afford to wait for this information when

View file

@ -309,16 +309,7 @@ static void handle_get_active_profile(DBusConnection *conn, DBusMessage *msg, vo
pa_assert(msg); pa_assert(msg);
pa_assert(c); pa_assert(c);
if (!c->active_profile) {
pa_assert(pa_hashmap_isempty(c->profiles));
pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
"The card %s has no profiles, and therefore there's no active profile either.", c->card->name);
return;
}
active_profile = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name)); active_profile = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name));
pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &active_profile); pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &active_profile);
} }
@ -333,15 +324,6 @@ static void handle_set_active_profile(DBusConnection *conn, DBusMessage *msg, DB
pa_assert(iter); pa_assert(iter);
pa_assert(c); pa_assert(c);
if (!c->active_profile) {
pa_assert(pa_hashmap_isempty(c->profiles));
pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
"The card %s has no profiles, and therefore there's no active profile either.",
c->card->name);
return;
}
dbus_message_iter_get_basic(iter, &new_active_path); dbus_message_iter_get_basic(iter, &new_active_path);
if (!(new_active = pa_hashmap_get(c->profiles, new_active_path))) { if (!(new_active = pa_hashmap_get(c->profiles, new_active_path))) {
@ -393,8 +375,7 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
sinks = get_sinks(c, &n_sinks); sinks = get_sinks(c, &n_sinks);
sources = get_sources(c, &n_sources); sources = get_sources(c, &n_sources);
profiles = get_profiles(c, &n_profiles); profiles = get_profiles(c, &n_profiles);
if (c->active_profile) active_profile = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name));
active_profile = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name));
pa_assert_se((reply = dbus_message_new_method_return(msg))); pa_assert_se((reply = dbus_message_new_method_return(msg)));
@ -411,9 +392,7 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks); pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks);
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_OBJECT_PATH, sources, n_sources); pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_OBJECT_PATH, sources, n_sources);
pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROFILES].property_name, DBUS_TYPE_OBJECT_PATH, profiles, n_profiles); pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROFILES].property_name, DBUS_TYPE_OBJECT_PATH, profiles, n_profiles);
pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACTIVE_PROFILE].property_name, DBUS_TYPE_OBJECT_PATH, &active_profile);
if (active_profile)
pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACTIVE_PROFILE].property_name, DBUS_TYPE_OBJECT_PATH, &active_profile);
pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, c->proplist); pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, c->proplist);
@ -501,6 +480,8 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card) { pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card) {
pa_dbusiface_card *c = NULL; pa_dbusiface_card *c = NULL;
pa_card_profile *profile;
void *state;
pa_assert(core); pa_assert(core);
pa_assert(card); pa_assert(card);
@ -511,20 +492,14 @@ pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card)
c->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, card->index); c->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, card->index);
c->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); c->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
c->next_profile_index = 0; c->next_profile_index = 0;
c->active_profile = NULL; c->active_profile = card->active_profile;
c->proplist = pa_proplist_copy(card->proplist); c->proplist = pa_proplist_copy(card->proplist);
c->dbus_protocol = pa_dbus_protocol_get(card->core); c->dbus_protocol = pa_dbus_protocol_get(card->core);
c->subscription = pa_subscription_new(card->core, PA_SUBSCRIPTION_MASK_CARD, subscription_cb, c); c->subscription = pa_subscription_new(card->core, PA_SUBSCRIPTION_MASK_CARD, subscription_cb, c);
if (card->profiles) { PA_HASHMAP_FOREACH(profile, card->profiles, state) {
pa_card_profile *profile; pa_dbusiface_card_profile *p = pa_dbusiface_card_profile_new(c, card->core, profile, c->next_profile_index++);
void *state = NULL; pa_hashmap_put(c->profiles, pa_dbusiface_card_profile_get_name(p), p);
PA_HASHMAP_FOREACH(profile, card->profiles, state) {
pa_dbusiface_card_profile *p = pa_dbusiface_card_profile_new(c, card->core, profile, c->next_profile_index++);
pa_hashmap_put(c->profiles, pa_dbusiface_card_profile_get_name(p), p);
}
pa_assert_se(c->active_profile = card->active_profile);
} }
pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, c->path, &card_interface_info, c) >= 0); pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, c->path, &card_interface_info, c) >= 0);

View file

@ -253,7 +253,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
return; return;
entry = entry_new(); entry = entry_new();
entry->profile = pa_xstrdup(card->active_profile ? card->active_profile->name : ""); entry->profile = pa_xstrdup(card->active_profile->name);
if ((old = entry_read(u, card->name))) { if ((old = entry_read(u, card->name))) {

View file

@ -60,10 +60,6 @@ static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) {
if (best_profile && best_profile->priority >= profile->priority) if (best_profile && best_profile->priority >= profile->priority)
continue; continue;
if (!card->active_profile) {
best_profile = profile;
continue;
}
/* We make a best effort to keep other direction unchanged */ /* We make a best effort to keep other direction unchanged */
if (!port->is_input) { if (!port->is_input) {
@ -156,7 +152,7 @@ static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port
find_sink_and_source(card, port, &sink, &source); find_sink_and_source(card, port, &sink, &source);
is_active_profile = port->profiles && card->active_profile && is_active_profile = port->profiles &&
card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name); card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name);
is_active_port = (sink && sink->active_port == port) || (source && source->active_port == port); is_active_port = (sink && sink->active_port == port) || (source && source->active_port == port);

View file

@ -67,6 +67,7 @@ pa_card_new_data* pa_card_new_data_init(pa_card_new_data *data) {
memset(data, 0, sizeof(*data)); memset(data, 0, sizeof(*data));
data->proplist = pa_proplist_new(); data->proplist = pa_proplist_new();
data->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
return data; return data;
} }
@ -114,6 +115,8 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
pa_core_assert_ref(core); pa_core_assert_ref(core);
pa_assert(data); pa_assert(data);
pa_assert(data->name); pa_assert(data->name);
pa_assert(data->profiles);
pa_assert(!pa_hashmap_isempty(data->profiles));
c = pa_xnew(pa_card, 1); c = pa_xnew(pa_card, 1);
@ -149,11 +152,11 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
c->active_profile = NULL; c->active_profile = NULL;
c->save_profile = FALSE; c->save_profile = FALSE;
if (data->active_profile && c->profiles) if (data->active_profile)
if ((c->active_profile = pa_hashmap_get(c->profiles, data->active_profile))) if ((c->active_profile = pa_hashmap_get(c->profiles, data->active_profile)))
c->save_profile = data->save_profile; c->save_profile = data->save_profile;
if (!c->active_profile && c->profiles) { if (!c->active_profile) {
void *state; void *state;
pa_card_profile *p; pa_card_profile *p;
@ -221,6 +224,7 @@ void pa_card_free(pa_card *c) {
int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) { int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {
pa_card_profile *profile; pa_card_profile *profile;
int r; int r;
pa_assert(c); pa_assert(c);
if (!c->set_profile) { if (!c->set_profile) {
@ -228,7 +232,7 @@ int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {
return -PA_ERR_NOTIMPLEMENTED; return -PA_ERR_NOTIMPLEMENTED;
} }
if (!c->profiles || !name) if (!name)
return -PA_ERR_NOENTITY; return -PA_ERR_NOENTITY;
if (!(profile = pa_hashmap_get(c->profiles, name))) if (!(profile = pa_hashmap_get(c->profiles, name)))

View file

@ -1840,8 +1840,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
nl = TRUE; nl = TRUE;
} }
if (card->active_profile) pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
} }
nl = FALSE; nl = FALSE;

View file

@ -149,6 +149,8 @@ char *pa_card_list_to_string(pa_core *c) {
pa_sink *sink; pa_sink *sink;
pa_source *source; pa_source *source;
uint32_t sidx; uint32_t sidx;
pa_card_profile *profile;
void *state;
pa_strbuf_printf( pa_strbuf_printf(
s, s,
@ -166,20 +168,14 @@ char *pa_card_list_to_string(pa_core *c) {
pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t); pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
pa_xfree(t); pa_xfree(t);
if (card->profiles) { pa_strbuf_puts(s, "\tprofiles:\n");
pa_card_profile *p; PA_HASHMAP_FOREACH(profile, card->profiles, state)
void *state; pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", profile->name, profile->description, profile->priority);
pa_strbuf_puts(s, "\tprofiles:\n"); pa_strbuf_printf(
PA_HASHMAP_FOREACH(p, card->profiles, state) s,
pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", p->name, p->description, p->priority); "\tactive profile: <%s>\n",
} card->active_profile->name);
if (card->active_profile)
pa_strbuf_printf(
s,
"\tactive profile: <%s>\n",
card->active_profile->name);
if (!pa_idxset_isempty(card->sinks)) { if (!pa_idxset_isempty(card->sinks)) {
pa_strbuf_puts(s, "\tsinks:\n"); pa_strbuf_puts(s, "\tsinks:\n");

View file

@ -3239,19 +3239,17 @@ static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_car
pa_tagstruct_putu32(t, card->module ? card->module->index : PA_INVALID_INDEX); pa_tagstruct_putu32(t, card->module ? card->module->index : PA_INVALID_INDEX);
pa_tagstruct_puts(t, card->driver); pa_tagstruct_puts(t, card->driver);
pa_tagstruct_putu32(t, card->profiles ? pa_hashmap_size(card->profiles) : 0); pa_tagstruct_putu32(t, pa_hashmap_size(card->profiles));
if (card->profiles) { PA_HASHMAP_FOREACH(p, card->profiles, state) {
while ((p = pa_hashmap_iterate(card->profiles, &state, NULL))) { pa_tagstruct_puts(t, p->name);
pa_tagstruct_puts(t, p->name); pa_tagstruct_puts(t, p->description);
pa_tagstruct_puts(t, p->description); pa_tagstruct_putu32(t, p->n_sinks);
pa_tagstruct_putu32(t, p->n_sinks); pa_tagstruct_putu32(t, p->n_sources);
pa_tagstruct_putu32(t, p->n_sources); pa_tagstruct_putu32(t, p->priority);
pa_tagstruct_putu32(t, p->priority);
}
} }
pa_tagstruct_puts(t, card->active_profile ? card->active_profile->name : NULL); pa_tagstruct_puts(t, card->active_profile->name);
pa_tagstruct_put_proplist(t, card->proplist); pa_tagstruct_put_proplist(t, card->proplist);
if (c->version < 26) if (c->version < 26)