]> code.delx.au - pulseaudio/blobdiff - src/modules/dbus/iface-device.c
bluetooth: Don't mark device valid before it has an adapter
[pulseaudio] / src / modules / dbus / iface-device.c
index 486a094668dd401b5a359805e613b30ac472d448..34b370b557c9b0fa573bb583b2f9157317a8591e 100644 (file)
@@ -43,13 +43,13 @@ static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, voi
 static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
 static void handle_get_has_flat_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_has_convertible_to_decibel_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_base_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_volume_steps(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_get_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_set_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
 static void handle_get_has_hardware_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_has_hardware_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_configured_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -60,7 +60,7 @@ static void handle_get_is_network_device(DBusConnection *conn, DBusMessage *msg,
 static void handle_get_state(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_ports(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_active_port(DBusConnection *conn, DBusMessage *msg, void *userdata);
-static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
 static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
 
 static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -76,11 +76,6 @@ static void handle_source_get_monitor_of_sink(DBusConnection *conn, DBusMessage
 
 static void handle_source_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
 
-enum device_type {
-    DEVICE_TYPE_SINK,
-    DEVICE_TYPE_SOURCE
-};
-
 struct pa_dbusiface_device {
     pa_dbusiface_core *core;
 
@@ -88,10 +83,10 @@ struct pa_dbusiface_device {
         pa_sink *sink;
         pa_source *source;
     };
-    enum device_type type;
+    pa_device_type_t type;
     char *path;
     pa_cvolume volume;
-    pa_bool_t is_muted;
+    dbus_bool_t mute;
     union {
         pa_sink_state_t sink_state;
         pa_source_state_t source_state;
@@ -119,7 +114,7 @@ enum property_handler_index {
     PROPERTY_HANDLER_HAS_CONVERTIBLE_TO_DECIBEL_VOLUME,
     PROPERTY_HANDLER_BASE_VOLUME,
     PROPERTY_HANDLER_VOLUME_STEPS,
-    PROPERTY_HANDLER_IS_MUTED,
+    PROPERTY_HANDLER_MUTE,
     PROPERTY_HANDLER_HAS_HARDWARE_VOLUME,
     PROPERTY_HANDLER_HAS_HARDWARE_MUTE,
     PROPERTY_HANDLER_CONFIGURED_LATENCY,
@@ -158,7 +153,7 @@ static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
     [PROPERTY_HANDLER_HAS_CONVERTIBLE_TO_DECIBEL_VOLUME] = { .property_name = "HasConvertibleToDecibelVolume", .type = "b",      .get_cb = handle_get_has_convertible_to_decibel_volume, .set_cb = NULL },
     [PROPERTY_HANDLER_BASE_VOLUME]                       = { .property_name = "BaseVolume",                    .type = "u",      .get_cb = handle_get_base_volume,                       .set_cb = NULL },
     [PROPERTY_HANDLER_VOLUME_STEPS]                      = { .property_name = "VolumeSteps",                   .type = "u",      .get_cb = handle_get_volume_steps,                      .set_cb = NULL },
-    [PROPERTY_HANDLER_IS_MUTED]                          = { .property_name = "IsMuted",                       .type = "b",      .get_cb = handle_get_is_muted,                          .set_cb = handle_set_is_muted },
+    [PROPERTY_HANDLER_MUTE]                              = { .property_name = "Mute",                          .type = "b",      .get_cb = handle_get_mute,                              .set_cb = handle_set_mute },
     [PROPERTY_HANDLER_HAS_HARDWARE_VOLUME]               = { .property_name = "HasHardwareVolume",             .type = "b",      .get_cb = handle_get_has_hardware_volume,               .set_cb = NULL },
     [PROPERTY_HANDLER_HAS_HARDWARE_MUTE]                 = { .property_name = "HasHardwareMute",               .type = "b",      .get_cb = handle_get_has_hardware_mute,                 .set_cb = NULL },
     [PROPERTY_HANDLER_CONFIGURED_LATENCY]                = { .property_name = "ConfiguredLatency",             .type = "t",      .get_cb = handle_get_configured_latency,                .set_cb = NULL },
@@ -266,7 +261,7 @@ static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userd
     pa_assert(msg);
     pa_assert(d);
 
-    idx = (d->type == DEVICE_TYPE_SINK) ? d->sink->index : d->source->index;
+    idx = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->index : d->source->index;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
 }
@@ -279,7 +274,7 @@ static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userda
     pa_assert(msg);
     pa_assert(d);
 
-    name = (d->type == DEVICE_TYPE_SINK) ? d->sink->name : d->source->name;
+    name = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->name : d->source->name;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &name);
 }
@@ -292,7 +287,7 @@ static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *user
     pa_assert(msg);
     pa_assert(d);
 
-    driver = (d->type == DEVICE_TYPE_SINK) ? d->sink->driver : d->source->driver;
+    driver = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->driver : d->source->driver;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &driver);
 }
@@ -306,10 +301,10 @@ static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void
     pa_assert(msg);
     pa_assert(d);
 
-    owner_module = (d->type == DEVICE_TYPE_SINK) ? d->sink->module : d->source->module;
+    owner_module = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->module : d->source->module;
 
     if (!owner_module) {
-        if (d->type == DEVICE_TYPE_SINK)
+        if (d->type == PA_DEVICE_TYPE_SINK)
             pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
                                "Sink %s doesn't have an owner module.", d->sink->name);
         else
@@ -332,10 +327,10 @@ static void handle_get_card(DBusConnection *conn, DBusMessage *msg, void *userda
     pa_assert(msg);
     pa_assert(d);
 
-    card = (d->type == DEVICE_TYPE_SINK) ? d->sink->card : d->source->card;
+    card = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->card : d->source->card;
 
     if (!card) {
-        if (d->type == DEVICE_TYPE_SINK)
+        if (d->type == PA_DEVICE_TYPE_SINK)
             pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
                                "Sink %s doesn't belong to any card.", d->sink->name);
         else
@@ -357,7 +352,7 @@ static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, voi
     pa_assert(msg);
     pa_assert(d);
 
-    sample_format = (d->type == DEVICE_TYPE_SINK) ? d->sink->sample_spec.format : d->source->sample_spec.format;
+    sample_format = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->sample_spec.format : d->source->sample_spec.format;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_format);
 }
@@ -370,7 +365,7 @@ static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void
     pa_assert(msg);
     pa_assert(d);
 
-    sample_rate = (d->type == DEVICE_TYPE_SINK) ? d->sink->sample_spec.rate : d->source->sample_spec.rate;
+    sample_rate = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->sample_spec.rate : d->source->sample_spec.rate;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_rate);
 }
@@ -385,7 +380,7 @@ static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *us
     pa_assert(msg);
     pa_assert(d);
 
-    channel_map = (d->type == DEVICE_TYPE_SINK) ? &d->sink->channel_map : &d->source->channel_map;
+    channel_map = (d->type == PA_DEVICE_TYPE_SINK) ? &d->sink->channel_map : &d->source->channel_map;
 
     for (i = 0; i < channel_map->channels; ++i)
         channels[i] = channel_map->map[i];
@@ -408,45 +403,46 @@ static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *user
     pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, volume, d->volume.channels);
 }
 
-static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
     pa_dbusiface_device *d = userdata;
-    unsigned device_channels = 0;
+    DBusMessageIter array_iter;
+    int device_channels = 0;
     dbus_uint32_t *volume = NULL;
-    unsigned n_volume_entries = 0;
+    int n_volume_entries = 0;
     pa_cvolume new_vol;
-    unsigned i = 0;
+    int i = 0;
 
     pa_assert(conn);
     pa_assert(msg);
+    pa_assert(iter);
     pa_assert(d);
 
-    pa_cvolume_init(&new_vol);
-
-    device_channels = (d->type == DEVICE_TYPE_SINK) ? d->sink->channel_map.channels : d->source->channel_map.channels;
-
-    new_vol.channels = device_channels;
+    device_channels = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->channel_map.channels : d->source->channel_map.channels;
 
-    if (pa_dbus_get_fixed_array_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &volume, &n_volume_entries) < 0)
-        return;
+    dbus_message_iter_recurse(iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &volume, &n_volume_entries);
 
-    if (n_volume_entries != device_channels) {
+    if (n_volume_entries != device_channels && n_volume_entries != 1) {
         pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
-                           "Expected %u volume entries, got %u.", device_channels, n_volume_entries);
+                           "Expected %u volume entries, got %i.", device_channels, n_volume_entries);
         return;
     }
 
+    pa_cvolume_init(&new_vol);
+    new_vol.channels = n_volume_entries;
+
     for (i = 0; i < n_volume_entries; ++i) {
-        if (volume[i] > PA_VOLUME_MAX) {
+        if (!PA_VOLUME_IS_VALID(volume[i])) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too large volume value: %u", volume[i]);
             return;
         }
         new_vol.values[i] = volume[i];
     }
 
-    if (d->type == DEVICE_TYPE_SINK)
-        pa_sink_set_volume(d->sink, &new_vol, TRUE, TRUE, TRUE, TRUE);
+    if (d->type == PA_DEVICE_TYPE_SINK)
+        pa_sink_set_volume(d->sink, &new_vol, true, true);
     else
-        pa_source_set_volume(d->source, &new_vol, TRUE);
+        pa_source_set_volume(d->source, &new_vol, true, true);
 
     pa_dbus_send_empty_reply(conn, msg);
 }
@@ -459,7 +455,7 @@ static void handle_get_has_flat_volume(DBusConnection *conn, DBusMessage *msg, v
     pa_assert(msg);
     pa_assert(d);
 
-    has_flat_volume = (d->type == DEVICE_TYPE_SINK) ? (d->sink->flags & PA_SINK_FLAT_VOLUME) : FALSE;
+    has_flat_volume = (d->type == PA_DEVICE_TYPE_SINK) ? !!(d->sink->flags & PA_SINK_FLAT_VOLUME) : FALSE;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_flat_volume);
 }
@@ -472,9 +468,9 @@ static void handle_get_has_convertible_to_decibel_volume(DBusConnection *conn, D
     pa_assert(msg);
     pa_assert(d);
 
-    has_convertible_to_decibel_volume = (d->type == DEVICE_TYPE_SINK)
-                                        ? (d->sink->flags & PA_SINK_DECIBEL_VOLUME)
-                                        : (d->source->flags & PA_SOURCE_DECIBEL_VOLUME);
+    has_convertible_to_decibel_volume = (d->type == PA_DEVICE_TYPE_SINK)
+                                        ? !!(d->sink->flags & PA_SINK_DECIBEL_VOLUME)
+                                        : !!(d->source->flags & PA_SOURCE_DECIBEL_VOLUME);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_convertible_to_decibel_volume);
 }
@@ -487,7 +483,7 @@ static void handle_get_base_volume(DBusConnection *conn, DBusMessage *msg, void
     pa_assert(msg);
     pa_assert(d);
 
-    base_volume = (d->type == DEVICE_TYPE_SINK) ? d->sink->base_volume : d->source->base_volume;
+    base_volume = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->base_volume : d->source->base_volume;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &base_volume);
 }
@@ -500,36 +496,36 @@ static void handle_get_volume_steps(DBusConnection *conn, DBusMessage *msg, void
     pa_assert(msg);
     pa_assert(d);
 
-    volume_steps = (d->type == DEVICE_TYPE_SINK) ? d->sink->n_volume_steps : d->source->n_volume_steps;
+    volume_steps = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->n_volume_steps : d->source->n_volume_steps;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &volume_steps);
 }
 
-static void handle_get_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_dbusiface_device *d = userdata;
 
     pa_assert(conn);
     pa_assert(msg);
     pa_assert(d);
 
-    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &d->is_muted);
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &d->mute);
 }
 
-static void handle_set_is_muted(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
     pa_dbusiface_device *d = userdata;
-    dbus_bool_t is_muted = FALSE;
+    dbus_bool_t mute = FALSE;
 
     pa_assert(conn);
     pa_assert(msg);
+    pa_assert(iter);
     pa_assert(d);
 
-    if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_BOOLEAN, &is_muted) < 0)
-        return;
+    dbus_message_iter_get_basic(iter, &mute);
 
-    if (d->type == DEVICE_TYPE_SINK)
-        pa_sink_set_mute(d->sink, is_muted, TRUE);
+    if (d->type == PA_DEVICE_TYPE_SINK)
+        pa_sink_set_mute(d->sink, mute, true);
     else
-        pa_source_set_mute(d->source, is_muted, TRUE);
+        pa_source_set_mute(d->source, mute, true);
 
     pa_dbus_send_empty_reply(conn, msg);
 }
@@ -542,9 +538,9 @@ static void handle_get_has_hardware_volume(DBusConnection *conn, DBusMessage *ms
     pa_assert(msg);
     pa_assert(d);
 
-    has_hardware_volume = (d->type == DEVICE_TYPE_SINK)
-                          ? (d->sink->flags & PA_SINK_HW_VOLUME_CTRL)
-                          : (d->source->flags & PA_SOURCE_HW_VOLUME_CTRL);
+    has_hardware_volume = (d->type == PA_DEVICE_TYPE_SINK)
+                          ? !!(d->sink->flags & PA_SINK_HW_VOLUME_CTRL)
+                          : !!(d->source->flags & PA_SOURCE_HW_VOLUME_CTRL);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_hardware_volume);
 }
@@ -557,9 +553,9 @@ static void handle_get_has_hardware_mute(DBusConnection *conn, DBusMessage *msg,
     pa_assert(msg);
     pa_assert(d);
 
-    has_hardware_mute = (d->type == DEVICE_TYPE_SINK)
-                        ? (d->sink->flags & PA_SINK_HW_MUTE_CTRL)
-                        : (d->source->flags & PA_SOURCE_HW_MUTE_CTRL);
+    has_hardware_mute = (d->type == PA_DEVICE_TYPE_SINK)
+                        ? !!(d->sink->flags & PA_SINK_HW_MUTE_CTRL)
+                        : !!(d->source->flags & PA_SOURCE_HW_MUTE_CTRL);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_hardware_mute);
 }
@@ -572,7 +568,7 @@ static void handle_get_configured_latency(DBusConnection *conn, DBusMessage *msg
     pa_assert(msg);
     pa_assert(d);
 
-    configured_latency = (d->type == DEVICE_TYPE_SINK)
+    configured_latency = (d->type == PA_DEVICE_TYPE_SINK)
                          ? pa_sink_get_requested_latency(d->sink)
                          : pa_source_get_requested_latency(d->source);
 
@@ -587,9 +583,9 @@ static void handle_get_has_dynamic_latency(DBusConnection *conn, DBusMessage *ms
     pa_assert(msg);
     pa_assert(d);
 
-    has_dynamic_latency = (d->type == DEVICE_TYPE_SINK)
-                          ? (d->sink->flags & PA_SINK_DYNAMIC_LATENCY)
-                          : (d->source->flags & PA_SOURCE_DYNAMIC_LATENCY);
+    has_dynamic_latency = (d->type == PA_DEVICE_TYPE_SINK)
+                          ? !!(d->sink->flags & PA_SINK_DYNAMIC_LATENCY)
+                          : !!(d->source->flags & PA_SOURCE_DYNAMIC_LATENCY);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_dynamic_latency);
 }
@@ -602,15 +598,19 @@ static void handle_get_latency(DBusConnection *conn, DBusMessage *msg, void *use
     pa_assert(msg);
     pa_assert(d);
 
-    if (d->type == DEVICE_TYPE_SINK && !(d->sink->flags & PA_SINK_LATENCY))
+    if (d->type == PA_DEVICE_TYPE_SINK && !(d->sink->flags & PA_SINK_LATENCY)) {
         pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
                            "Sink %s doesn't support latency querying.", d->sink->name);
-    else if (d->type == DEVICE_TYPE_SOURCE && !(d->source->flags & PA_SOURCE_LATENCY))
+        return;
+    }
+
+    if (d->type == PA_DEVICE_TYPE_SOURCE && !(d->source->flags & PA_SOURCE_LATENCY)) {
         pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
                            "Source %s doesn't support latency querying.", d->source->name);
-    return;
+        return;
+    }
 
-    latency = (d->type == DEVICE_TYPE_SINK) ? pa_sink_get_latency(d->sink) : pa_source_get_latency(d->source);
+    latency = (d->type == PA_DEVICE_TYPE_SINK) ? pa_sink_get_latency(d->sink) : pa_source_get_latency(d->source);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT64, &latency);
 }
@@ -623,9 +623,9 @@ static void handle_get_is_hardware_device(DBusConnection *conn, DBusMessage *msg
     pa_assert(msg);
     pa_assert(d);
 
-    is_hardware_device = (d->type == DEVICE_TYPE_SINK)
-                         ? (d->sink->flags & PA_SINK_HARDWARE)
-                         : (d->source->flags & PA_SOURCE_HARDWARE);
+    is_hardware_device = (d->type == PA_DEVICE_TYPE_SINK)
+                         ? !!(d->sink->flags & PA_SINK_HARDWARE)
+                         : !!(d->source->flags & PA_SOURCE_HARDWARE);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_hardware_device);
 }
@@ -638,9 +638,9 @@ static void handle_get_is_network_device(DBusConnection *conn, DBusMessage *msg,
     pa_assert(msg);
     pa_assert(d);
 
-    is_network_device = (d->type == DEVICE_TYPE_SINK)
-                        ? (d->sink->flags & PA_SINK_NETWORK)
-                        : (d->source->flags & PA_SOURCE_NETWORK);
+    is_network_device = (d->type == PA_DEVICE_TYPE_SINK)
+                        ? !!(d->sink->flags & PA_SINK_NETWORK)
+                        : !!(d->source->flags & PA_SOURCE_NETWORK);
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_network_device);
 }
@@ -653,7 +653,7 @@ static void handle_get_state(DBusConnection *conn, DBusMessage *msg, void *userd
     pa_assert(msg);
     pa_assert(d);
 
-    state = (d->type == DEVICE_TYPE_SINK) ? d->sink_state : d->source_state;
+    state = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink_state : d->source_state;
 
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &state);
 }
@@ -708,7 +708,7 @@ static void handle_get_active_port(DBusConnection *conn, DBusMessage *msg, void
     if (!d->active_port) {
         pa_assert(pa_hashmap_isempty(d->ports));
 
-        if (d->type == DEVICE_TYPE_SINK)
+        if (d->type == PA_DEVICE_TYPE_SINK)
             pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
                                "The sink %s has no ports, and therefore there's no active port either.", d->sink->name);
         else
@@ -722,7 +722,7 @@ static void handle_get_active_port(DBusConnection *conn, DBusMessage *msg, void
     pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &active_port);
 }
 
-static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
     pa_dbusiface_device *d = userdata;
     const char *new_active_path;
     pa_dbusiface_device_port *new_active;
@@ -730,15 +730,13 @@ static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, void
 
     pa_assert(conn);
     pa_assert(msg);
+    pa_assert(iter);
     pa_assert(d);
 
-    if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_OBJECT_PATH, &new_active_path) < 0)
-        return;
-
     if (!d->active_port) {
         pa_assert(pa_hashmap_isempty(d->ports));
 
-        if (d->type == DEVICE_TYPE_SINK)
+        if (d->type == PA_DEVICE_TYPE_SINK)
             pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
                                "The sink %s has no ports, and therefore there's no active port either.", d->sink->name);
         else
@@ -747,19 +745,21 @@ static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, void
         return;
     }
 
+    dbus_message_iter_get_basic(iter, &new_active_path);
+
     if (!(new_active = pa_hashmap_get(d->ports, new_active_path))) {
-        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such port.", new_active_path);
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such port: %s", new_active_path);
         return;
     }
 
-    if (d->type == DEVICE_TYPE_SINK) {
-        if ((r = pa_sink_set_port(d->sink, pa_dbusiface_device_port_get_name(new_active), TRUE)) < 0) {
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        if ((r = pa_sink_set_port(d->sink, pa_dbusiface_device_port_get_name(new_active), true)) < 0) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
                                "Internal error in PulseAudio: pa_sink_set_port() failed with error code %i.", r);
             return;
         }
     } else {
-        if ((r = pa_source_set_port(d->source, pa_dbusiface_device_port_get_name(new_active), TRUE)) < 0) {
+        if ((r = pa_source_set_port(d->source, pa_dbusiface_device_port_get_name(new_active), true)) < 0) {
             pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
                                "Internal error in PulseAudio: pa_source_set_port() failed with error code %i.", r);
             return;
@@ -817,48 +817,57 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
     pa_assert(msg);
     pa_assert(d);
 
-    idx = (d->type == DEVICE_TYPE_SINK) ? d->sink->index : d->source->index;
-    name = (d->type == DEVICE_TYPE_SINK) ? d->sink->name : d->source->name;
-    driver = (d->type == DEVICE_TYPE_SINK) ? d->sink->driver : d->source->driver;
-    owner_module = (d->type == DEVICE_TYPE_SINK) ? d->sink->module : d->source->module;
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        idx = d->sink->index;
+        name = d->sink->name;
+        driver = d->sink->driver;
+        owner_module = d->sink->module;
+        card = d->sink->card;
+        sample_format = d->sink->sample_spec.format;
+        sample_rate = d->sink->sample_spec.rate;
+        channel_map = &d->sink->channel_map;
+        has_flat_volume = !!(d->sink->flags & PA_SINK_FLAT_VOLUME);
+        has_convertible_to_decibel_volume = !!(d->sink->flags & PA_SINK_DECIBEL_VOLUME);
+        base_volume = d->sink->base_volume;
+        volume_steps = d->sink->n_volume_steps;
+        has_hardware_volume = !!(d->sink->flags & PA_SINK_HW_VOLUME_CTRL);
+        has_hardware_mute = !!(d->sink->flags & PA_SINK_HW_MUTE_CTRL);
+        configured_latency = pa_sink_get_requested_latency(d->sink);
+        has_dynamic_latency = !!(d->sink->flags & PA_SINK_DYNAMIC_LATENCY);
+        latency = pa_sink_get_latency(d->sink);
+        is_hardware_device = !!(d->sink->flags & PA_SINK_HARDWARE);
+        is_network_device = !!(d->sink->flags & PA_SINK_NETWORK);
+        state = pa_sink_get_state(d->sink);
+    } else {
+        idx = d->source->index;
+        name = d->source->name;
+        driver = d->source->driver;
+        owner_module = d->source->module;
+        card = d->source->card;
+        sample_format = d->source->sample_spec.format;
+        sample_rate = d->source->sample_spec.rate;
+        channel_map = &d->source->channel_map;
+        has_flat_volume = FALSE;
+        has_convertible_to_decibel_volume = !!(d->source->flags & PA_SOURCE_DECIBEL_VOLUME);
+        base_volume = d->source->base_volume;
+        volume_steps = d->source->n_volume_steps;
+        has_hardware_volume = !!(d->source->flags & PA_SOURCE_HW_VOLUME_CTRL);
+        has_hardware_mute = !!(d->source->flags & PA_SOURCE_HW_MUTE_CTRL);
+        configured_latency = pa_source_get_requested_latency(d->source);
+        has_dynamic_latency = !!(d->source->flags & PA_SOURCE_DYNAMIC_LATENCY);
+        latency = pa_source_get_latency(d->source);
+        is_hardware_device = !!(d->source->flags & PA_SOURCE_HARDWARE);
+        is_network_device = !!(d->source->flags & PA_SOURCE_NETWORK);
+        state = pa_source_get_state(d->source);
+    }
     if (owner_module)
         owner_module_path = pa_dbusiface_core_get_module_path(d->core, owner_module);
-    card = (d->type == DEVICE_TYPE_SINK) ? d->sink->card : d->source->card;
     if (card)
         card_path = pa_dbusiface_core_get_card_path(d->core, card);
-    sample_format = (d->type == DEVICE_TYPE_SINK) ? d->sink->sample_spec.format : d->source->sample_spec.format;
-    sample_rate = (d->type == DEVICE_TYPE_SINK) ? d->sink->sample_spec.rate : d->source->sample_spec.rate;
-    channel_map = (d->type == DEVICE_TYPE_SINK) ? &d->sink->channel_map : &d->source->channel_map;
     for (i = 0; i < channel_map->channels; ++i)
         channels[i] = channel_map->map[i];
     for (i = 0; i < d->volume.channels; ++i)
         volume[i] = d->volume.values[i];
-    has_flat_volume = (d->type == DEVICE_TYPE_SINK) ? (d->sink->flags & PA_SINK_FLAT_VOLUME) : FALSE;
-    has_convertible_to_decibel_volume = (d->type == DEVICE_TYPE_SINK)
-                                        ? (d->sink->flags & PA_SINK_DECIBEL_VOLUME)
-                                        : (d->source->flags & PA_SOURCE_DECIBEL_VOLUME);
-    base_volume = (d->type == DEVICE_TYPE_SINK) ? d->sink->base_volume : d->source->base_volume;
-    volume_steps = (d->type == DEVICE_TYPE_SINK) ? d->sink->n_volume_steps : d->source->n_volume_steps;
-    has_hardware_volume = (d->type == DEVICE_TYPE_SINK)
-                          ? (d->sink->flags & PA_SINK_HW_VOLUME_CTRL)
-                          : (d->source->flags & PA_SOURCE_HW_VOLUME_CTRL);
-    has_hardware_mute = (d->type == DEVICE_TYPE_SINK)
-                        ? (d->sink->flags & PA_SINK_HW_MUTE_CTRL)
-                        : (d->source->flags & PA_SOURCE_HW_MUTE_CTRL);
-    configured_latency = (d->type == DEVICE_TYPE_SINK)
-                         ? pa_sink_get_requested_latency(d->sink)
-                         : pa_source_get_requested_latency(d->source);
-    has_dynamic_latency = (d->type == DEVICE_TYPE_SINK)
-                          ? (d->sink->flags & PA_SINK_DYNAMIC_LATENCY)
-                          : (d->source->flags & PA_SOURCE_DYNAMIC_LATENCY);
-    latency = (d->type == DEVICE_TYPE_SINK) ? pa_sink_get_latency(d->sink) : pa_source_get_latency(d->source);
-    is_hardware_device = (d->type == DEVICE_TYPE_SINK)
-                         ? (d->sink->flags & PA_SINK_HARDWARE)
-                         : (d->source->flags & PA_SOURCE_HARDWARE);
-    is_network_device = (d->type == DEVICE_TYPE_SINK)
-                        ? (d->sink->flags & PA_SINK_NETWORK)
-                        : (d->source->flags & PA_SOURCE_NETWORK);
-    state = (d->type == DEVICE_TYPE_SINK) ? pa_sink_get_state(d->sink) : pa_source_get_state(d->source);
     ports = get_ports(d, &n_ports);
     if (d->active_port)
         active_port = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name));
@@ -886,7 +895,7 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_CONVERTIBLE_TO_DECIBEL_VOLUME].property_name, DBUS_TYPE_BOOLEAN, &has_convertible_to_decibel_volume);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_BASE_VOLUME].property_name, DBUS_TYPE_UINT32, &base_volume);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VOLUME_STEPS].property_name, DBUS_TYPE_UINT32, &volume_steps);
-    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_IS_MUTED].property_name, DBUS_TYPE_BOOLEAN, &d->is_muted);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &d->mute);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_HARDWARE_VOLUME].property_name, DBUS_TYPE_BOOLEAN, &has_hardware_volume);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_HARDWARE_MUTE].property_name, DBUS_TYPE_BOOLEAN, &has_hardware_mute);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CONFIGURED_LATENCY].property_name, DBUS_TYPE_UINT64, &configured_latency);
@@ -914,20 +923,30 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
 static void handle_suspend(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_dbusiface_device *d = userdata;
     dbus_bool_t suspend = FALSE;
+    pa_client *client;
 
     pa_assert(conn);
     pa_assert(msg);
     pa_assert(d);
 
-    if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_BOOLEAN, &suspend) < 0)
-        return;
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &suspend, DBUS_TYPE_INVALID));
+    pa_assert_se(client = pa_dbus_protocol_get_client(d->dbus_protocol, conn));
 
-    if ((d->type == DEVICE_TYPE_SINK) && (pa_sink_suspend(d->sink, suspend, PA_SUSPEND_USER) < 0)) {
-        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error in PulseAudio: pa_sink_suspend() failed.");
-        return;
-    } else if ((d->type == DEVICE_TYPE_SOURCE) && (pa_source_suspend(d->source, suspend, PA_SUSPEND_USER) < 0)) {
-        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error in PulseAudio: pa_source_suspend() failed.");
-        return;
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        pa_log_debug("%s sink %s requested by client %" PRIu32 ".", suspend ? "Suspending" : "Resuming", d->sink->name, client->index);
+
+        if (pa_sink_suspend(d->sink, suspend, PA_SUSPEND_USER) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error in PulseAudio: pa_sink_suspend() failed.");
+            return;
+        }
+
+    } else {
+        pa_log_debug("%s source %s requested by client %" PRIu32 ".", suspend ? "Suspending" : "Resuming", d->source->name, client->index);
+
+        if (pa_source_suspend(d->source, suspend, PA_SUSPEND_USER) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error in PulseAudio: pa_source_suspend() failed.");
+            return;
+        }
     }
 
     pa_dbus_send_empty_reply(conn, msg);
@@ -935,7 +954,6 @@ static void handle_suspend(DBusConnection *conn, DBusMessage *msg, void *userdat
 
 static void handle_get_port_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_dbusiface_device *d = userdata;
-    DBusError error;
     const char *port_name = NULL;
     pa_dbusiface_device_port *port = NULL;
     const char *port_path = NULL;
@@ -944,16 +962,10 @@ static void handle_get_port_by_name(DBusConnection *conn, DBusMessage *msg, void
     pa_assert(msg);
     pa_assert(d);
 
-    dbus_error_init(&error);
-
-    if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &port_name, DBUS_TYPE_INVALID)) {
-        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
-        dbus_error_free(&error);
-        return;
-    }
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &port_name, DBUS_TYPE_INVALID));
 
     if (!(port = pa_hashmap_get(d->ports, port_name))) {
-        if (d->type == DEVICE_TYPE_SINK)
+        if (d->type == PA_DEVICE_TYPE_SINK)
             pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND,
                                "%s: No such port on sink %s.", port_name, d->sink->name);
         else
@@ -974,7 +986,7 @@ static void handle_sink_get_monitor_source(DBusConnection *conn, DBusMessage *ms
     pa_assert(conn);
     pa_assert(msg);
     pa_assert(d);
-    pa_assert(d->type == DEVICE_TYPE_SINK);
+    pa_assert(d->type == PA_DEVICE_TYPE_SINK);
 
     monitor_source = pa_dbusiface_core_get_source_path(d->core, d->sink->monitor_source);
 
@@ -991,7 +1003,7 @@ static void handle_sink_get_all(DBusConnection *conn, DBusMessage *msg, void *us
     pa_assert(conn);
     pa_assert(msg);
     pa_assert(d);
-    pa_assert(d->type == DEVICE_TYPE_SINK);
+    pa_assert(d->type == PA_DEVICE_TYPE_SINK);
 
     monitor_source = pa_dbusiface_core_get_source_path(d->core, d->sink->monitor_source);
 
@@ -1016,7 +1028,7 @@ static void handle_source_get_monitor_of_sink(DBusConnection *conn, DBusMessage
     pa_assert(conn);
     pa_assert(msg);
     pa_assert(d);
-    pa_assert(d->type == DEVICE_TYPE_SOURCE);
+    pa_assert(d->type == PA_DEVICE_TYPE_SOURCE);
 
     if (!d->source->monitor_of) {
         pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Source %s is not a monitor source.", d->source->name);
@@ -1038,7 +1050,7 @@ static void handle_source_get_all(DBusConnection *conn, DBusMessage *msg, void *
     pa_assert(conn);
     pa_assert(msg);
     pa_assert(d);
-    pa_assert(d->type == DEVICE_TYPE_SOURCE);
+    pa_assert(d->type == PA_DEVICE_TYPE_SOURCE);
 
     if (d->source->monitor_of)
         monitor_of_sink = pa_dbusiface_core_get_sink_path(d->core, d->source->monitor_of);
@@ -1060,131 +1072,136 @@ static void handle_source_get_all(DBusConnection *conn, DBusMessage *msg, void *
 
 static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
     pa_dbusiface_device *d = userdata;
+    DBusMessage *signal_msg = NULL;
+    const pa_cvolume *new_volume = NULL;
+    bool new_mute = false;
+    pa_sink_state_t new_sink_state = 0;
+    pa_source_state_t new_source_state = 0;
+    pa_device_port *new_active_port = NULL;
+    pa_proplist *new_proplist = NULL;
+    unsigned i = 0;
 
     pa_assert(c);
     pa_assert(d);
 
-    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE) {
-        DBusMessage *signal = NULL;
-        const pa_cvolume *new_volume = NULL;
-        pa_bool_t new_muted = FALSE;
-        pa_sink_state_t new_sink_state = 0;
-        pa_source_state_t new_source_state = 0;
-        pa_device_port *new_active_port = NULL;
-        pa_proplist *new_proplist = NULL;
-        unsigned i = 0;
+    if ((d->type == PA_DEVICE_TYPE_SINK && idx != d->sink->index) || (d->type == PA_DEVICE_TYPE_SOURCE && idx != d->source->index))
+        return;
 
-        pa_assert(((d->type == DEVICE_TYPE_SINK)
-                    && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK))
-                  || ((d->type == DEVICE_TYPE_SOURCE)
-                       && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE)));
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
 
-        new_volume = (d->type == DEVICE_TYPE_SINK)
-                     ? pa_sink_get_volume(d->sink, FALSE, FALSE)
-                     : pa_source_get_volume(d->source, FALSE);
+    pa_assert(((d->type == PA_DEVICE_TYPE_SINK)
+                && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK))
+              || ((d->type == PA_DEVICE_TYPE_SOURCE)
+                   && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE)));
 
-        if (!pa_cvolume_equal(&d->volume, new_volume)) {
-            dbus_uint32_t volume[PA_CHANNELS_MAX];
-            dbus_uint32_t *volume_ptr = volume;
+    new_volume = (d->type == PA_DEVICE_TYPE_SINK)
+                 ? pa_sink_get_volume(d->sink, false)
+                 : pa_source_get_volume(d->source, false);
 
-            d->volume = *new_volume;
+    if (!pa_cvolume_equal(&d->volume, new_volume)) {
+        dbus_uint32_t volume[PA_CHANNELS_MAX];
+        dbus_uint32_t *volume_ptr = volume;
 
-            for (i = 0; i < d->volume.channels; ++i)
-                volume[i] = d->volume.values[i];
+        d->volume = *new_volume;
 
-            pa_assert_se(signal = dbus_message_new_signal(d->path,
+        for (i = 0; i < d->volume.channels; ++i)
+            volume[i] = d->volume.values[i];
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
                                                           PA_DBUSIFACE_DEVICE_INTERFACE,
                                                           signals[SIGNAL_VOLUME_UPDATED].name));
-            pa_assert_se(dbus_message_append_args(signal,
-                                                  DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, d->volume.channels,
-                                                  DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(signal_msg,
+                                              DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, d->volume.channels,
+                                              DBUS_TYPE_INVALID));
 
-            pa_dbus_protocol_send_signal(d->dbus_protocol, signal);
-            dbus_message_unref(signal);
-            signal = NULL;
-        }
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
 
-        new_muted = (d->type == DEVICE_TYPE_SINK) ? pa_sink_get_mute(d->sink, FALSE) : pa_source_get_mute(d->source, FALSE);
+    new_mute = (d->type == PA_DEVICE_TYPE_SINK) ? pa_sink_get_mute(d->sink, false) : pa_source_get_mute(d->source, false);
 
-        if (d->is_muted != new_muted) {
-            d->is_muted = new_muted;
+    if (d->mute != new_mute) {
+        d->mute = new_mute;
 
-            pa_assert_se(signal = dbus_message_new_signal(d->path,
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
                                                           PA_DBUSIFACE_DEVICE_INTERFACE,
                                                           signals[SIGNAL_MUTE_UPDATED].name));
-            pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_BOOLEAN, &d->is_muted, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &d->mute, DBUS_TYPE_INVALID));
 
-            pa_dbus_protocol_send_signal(d->dbus_protocol, signal);
-            dbus_message_unref(signal);
-            signal = NULL;
-        }
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
 
-        if (d->type == DEVICE_TYPE_SINK)
-            new_sink_state = pa_sink_get_state(d->sink);
-        else
-            new_source_state = pa_source_get_state(d->source);
+    if (d->type == PA_DEVICE_TYPE_SINK)
+        new_sink_state = pa_sink_get_state(d->sink);
+    else
+        new_source_state = pa_source_get_state(d->source);
 
-        if ((d->type == DEVICE_TYPE_SINK && d->sink_state != new_sink_state)
-            || (d->type == DEVICE_TYPE_SOURCE && d->source_state != new_source_state)) {
-            dbus_uint32_t state = 0;
+    if ((d->type == PA_DEVICE_TYPE_SINK && d->sink_state != new_sink_state)
+        || (d->type == PA_DEVICE_TYPE_SOURCE && d->source_state != new_source_state)) {
+        dbus_uint32_t state = 0;
 
-            if (d->type == DEVICE_TYPE_SINK)
-                d->sink_state = new_sink_state;
-            else
-                d->source_state = new_source_state;
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            d->sink_state = new_sink_state;
+        else
+            d->source_state = new_source_state;
 
-            state = (d->type == DEVICE_TYPE_SINK) ? d->sink_state : d->source_state;
+        state = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink_state : d->source_state;
 
-            pa_assert_se(signal = dbus_message_new_signal(d->path,
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
                                                           PA_DBUSIFACE_DEVICE_INTERFACE,
                                                           signals[SIGNAL_STATE_UPDATED].name));
-            pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID));
 
-            pa_dbus_protocol_send_signal(d->dbus_protocol, signal);
-            dbus_message_unref(signal);
-            signal = NULL;
-        }
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
 
-        new_active_port = (d->type == DEVICE_TYPE_SINK) ? d->sink->active_port : d->source->active_port;
+    new_active_port = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->active_port : d->source->active_port;
 
-        if (d->active_port != new_active_port) {
-            const char *object_path = NULL;
+    if (d->active_port != new_active_port) {
+        const char *object_path = NULL;
 
-            d->active_port = new_active_port;
-            object_path = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name));
+        d->active_port = new_active_port;
+        object_path = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name));
 
-            pa_assert_se(signal = dbus_message_new_signal(d->path,
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
                                                           PA_DBUSIFACE_DEVICE_INTERFACE,
                                                           signals[SIGNAL_ACTIVE_PORT_UPDATED].name));
-            pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
-            pa_dbus_protocol_send_signal(d->dbus_protocol, signal);
-            dbus_message_unref(signal);
-            signal = NULL;
-        }
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
 
-        new_proplist = (d->type == DEVICE_TYPE_SINK) ? d->sink->proplist : d->source->proplist;
+    new_proplist = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->proplist : d->source->proplist;
 
-        if (!pa_proplist_equal(d->proplist, new_proplist)) {
-            DBusMessageIter msg_iter;
+    if (!pa_proplist_equal(d->proplist, new_proplist)) {
+        DBusMessageIter msg_iter;
 
-            pa_proplist_update(d->proplist, PA_UPDATE_SET, new_proplist);
+        pa_proplist_update(d->proplist, PA_UPDATE_SET, new_proplist);
 
-            pa_assert_se(signal = dbus_message_new_signal(d->path,
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
                                                           PA_DBUSIFACE_DEVICE_INTERFACE,
                                                           signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
-            dbus_message_iter_init_append(signal, &msg_iter);
-            pa_dbus_append_proplist(&msg_iter, d->proplist);
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, d->proplist);
 
-            pa_dbus_protocol_send_signal(d->dbus_protocol, signal);
-            dbus_message_unref(signal);
-            signal = NULL;
-        }
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
     }
 }
 
 pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_sink *sink) {
     pa_dbusiface_device *d = NULL;
+    pa_device_port *port;
+    void *state;
 
     pa_assert(core);
     pa_assert(sink);
@@ -1192,27 +1209,21 @@ pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_si
     d = pa_xnew0(pa_dbusiface_device, 1);
     d->core = core;
     d->sink = pa_sink_ref(sink);
-    d->type = DEVICE_TYPE_SINK;
+    d->type = PA_DEVICE_TYPE_SINK;
     d->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, SINK_OBJECT_NAME, sink->index);
-    d->volume = *pa_sink_get_volume(sink, FALSE, FALSE);
-    d->is_muted = pa_sink_get_mute(sink, FALSE);
+    d->volume = *pa_sink_get_volume(sink, false);
+    d->mute = pa_sink_get_mute(sink, false);
     d->sink_state = pa_sink_get_state(sink);
-    d->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    d->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_device_port_free);
     d->next_port_index = 0;
-    d->active_port = NULL;
+    d->active_port = sink->active_port;
     d->proplist = pa_proplist_copy(sink->proplist);
     d->dbus_protocol = pa_dbus_protocol_get(sink->core);
     d->subscription = pa_subscription_new(sink->core, PA_SUBSCRIPTION_MASK_SINK, subscription_cb, d);
 
-    if (sink->ports) {
-        pa_device_port *port;
-        void *state = NULL;
-
-        PA_HASHMAP_FOREACH(port, sink->ports, state) {
-            pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, sink->core, port, d->next_port_index++);
-            pa_hashmap_put(d->ports, pa_dbusiface_device_port_get_name(p), p);
-        }
-        pa_assert_se(d->active_port = sink->active_port);
+    PA_HASHMAP_FOREACH(port, sink->ports, state) {
+        pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, sink->core, port, d->next_port_index++);
+        pa_hashmap_put(d->ports, (char *) pa_dbusiface_device_port_get_name(p), p);
     }
 
     pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &device_interface_info, d) >= 0);
@@ -1223,6 +1234,8 @@ pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_si
 
 pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_source *source) {
     pa_dbusiface_device *d = NULL;
+    pa_device_port *port;
+    void *state;
 
     pa_assert(core);
     pa_assert(source);
@@ -1230,27 +1243,21 @@ pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_
     d = pa_xnew0(pa_dbusiface_device, 1);
     d->core = core;
     d->source = pa_source_ref(source);
-    d->type = DEVICE_TYPE_SOURCE;
+    d->type = PA_DEVICE_TYPE_SOURCE;
     d->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, SOURCE_OBJECT_NAME, source->index);
-    d->volume = *pa_source_get_volume(source, FALSE);
-    d->is_muted = pa_source_get_mute(source, FALSE);
+    d->volume = *pa_source_get_volume(source, false);
+    d->mute = pa_source_get_mute(source, false);
     d->source_state = pa_source_get_state(source);
     d->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     d->next_port_index = 0;
-    d->active_port = NULL;
+    d->active_port = source->active_port;
     d->proplist = pa_proplist_copy(source->proplist);
     d->dbus_protocol = pa_dbus_protocol_get(source->core);
     d->subscription = pa_subscription_new(source->core, PA_SUBSCRIPTION_MASK_SOURCE, subscription_cb, d);
 
-    if (source->ports) {
-        pa_device_port *port;
-        void *state = NULL;
-
-        PA_HASHMAP_FOREACH(port, source->ports, state) {
-            pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, source->core, port, d->next_port_index++);
-            pa_hashmap_put(d->ports, pa_dbusiface_device_port_get_name(p), p);
-        }
-        pa_assert_se(d->active_port = source->active_port);
+    PA_HASHMAP_FOREACH(port, source->ports, state) {
+        pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, source->core, port, d->next_port_index++);
+        pa_hashmap_put(d->ports, (char *) pa_dbusiface_device_port_get_name(p), p);
     }
 
     pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &device_interface_info, d) >= 0);
@@ -1259,20 +1266,12 @@ pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_
     return d;
 }
 
-static void port_free_cb(void *p, void *userdata) {
-    pa_dbusiface_device_port *port = p;
-
-    pa_assert(port);
-
-    pa_dbusiface_device_port_free(port);
-}
-
 void pa_dbusiface_device_free(pa_dbusiface_device *d) {
     pa_assert(d);
 
     pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, device_interface_info.name) >= 0);
 
-    if (d->type == DEVICE_TYPE_SINK) {
+    if (d->type == PA_DEVICE_TYPE_SINK) {
         pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, sink_interface_info.name) >= 0);
         pa_sink_unref(d->sink);
 
@@ -1280,7 +1279,7 @@ void pa_dbusiface_device_free(pa_dbusiface_device *d) {
         pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, source_interface_info.name) >= 0);
         pa_source_unref(d->source);
     }
-    pa_hashmap_free(d->ports, port_free_cb, NULL);
+    pa_hashmap_free(d->ports);
     pa_proplist_free(d->proplist);
     pa_dbus_protocol_unref(d->dbus_protocol);
     pa_subscription_free(d->subscription);
@@ -1297,14 +1296,14 @@ const char *pa_dbusiface_device_get_path(pa_dbusiface_device *d) {
 
 pa_sink *pa_dbusiface_device_get_sink(pa_dbusiface_device *d) {
     pa_assert(d);
-    pa_assert(d->type == DEVICE_TYPE_SINK);
+    pa_assert(d->type == PA_DEVICE_TYPE_SINK);
 
     return d->sink;
 }
 
 pa_source *pa_dbusiface_device_get_source(pa_dbusiface_device *d) {
     pa_assert(d);
-    pa_assert(d->type == DEVICE_TYPE_SOURCE);
+    pa_assert(d->type == PA_DEVICE_TYPE_SOURCE);
 
     return d->source;
 }