pa_assert(u);
pa_assert(u->capability);
-
+ pa_assert(!pa_hashmap_get(u->devices, udi));
+
#ifdef HAVE_ALSA
if (strcmp(u->capability, CAPABILITY_ALSA) == 0)
m = hal_device_load_alsa(u, udi, &sink_name, &source_name);
static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const struct timeval *tv, void *userdata) {
DBusError error;
struct timerdata *td = userdata;
- int b;
- struct device *d;
dbus_error_init(&error);
-
- b = libhal_device_exists(td->u->context, td->udi, &error);
-
- if (dbus_error_is_set(&error)) {
- pa_log_error("Error adding device: %s: %s", error.name, error.message);
- dbus_error_free(&error);
- } else if (b) {
- if (!(d = hal_device_add(td->u, td->udi)))
- pa_log_debug("Not loaded device %s", td->udi);
- else {
- if (d->sink_name)
- pa_scache_play_item_by_name(td->u->core, "pulse-hotplug", d->sink_name, PA_VOLUME_NORM, 0);
+
+ if (!pa_hashmap_get(td->u->devices, td->udi)) {
+ int b;
+ struct device *d;
+
+ b = libhal_device_exists(td->u->context, td->udi, &error);
+
+ if (dbus_error_is_set(&error)) {
+ pa_log_error("Error adding device: %s: %s", error.name, error.message);
+ dbus_error_free(&error);
+ } else if (b) {
+ if (!(d = hal_device_add(td->u, td->udi)))
+ pa_log_debug("Not loaded device %s", td->udi);
+ else {
+ if (d->sink_name)
+ pa_scache_play_item_by_name(td->u->core, "pulse-hotplug", d->sink_name, PA_VOLUME_NORM, 0);
+ }
}
}
int good = 0;
pa_assert_se(u = libhal_ctx_get_user_data(context));
+
+ if (pa_hashmap_get(u->devices, udi))
+ return;
pa_log_debug("HAL Device added: %s", udi);
device_removed_cb(context, udi);
}
-
static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
struct userdata*u = userdata;
DBusError error;
if (d->sink_name) {
pa_sink *sink;
- if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0)))
- if (pa_sink_suspend(sink, suspend) >= 0)
- pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0);
+ if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) {
+
+ int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED;
+
+ if (pa_sink_suspend(sink, suspend) >= 0) {
+ if (!suspend && prev_suspended)
+ pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0);
+ else if (suspend && !prev_suspended) {
+ DBusMessage *msg;
+ msg = dbus_message_new_signal(udi, "org.pulseaudio.Server", "DirtyGiveUpMessage");
+ dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL);
+ dbus_message_unref(msg);
+ }
+ }
+ }
}
if (d->source_name) {
if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0)))
pa_source_suspend(source, suspend);
}
- }
-
+
+ } else if (!suspend)
+ device_added_cb(u->context, udi);
}
+ } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) {
+ /* We use this message to avoid a dirty race condition when we
+ get an ACLAdded message before the previously owning PA
+ sever has closed the device. We can remove this as
+ soon as HAL learns frevoke() */
+
+ const char *udi;
+ struct device *d;
+
+ pa_log_debug("Got dirty give up message, trying resume ...");
+
+ udi = dbus_message_get_path(message);
+
+ if ((d = pa_hashmap_get(u->devices, udi))) {
+
+ if (d->sink_name) {
+ pa_sink *sink;
+
+ if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) {
+
+ int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED;
+
+ if (pa_sink_suspend(sink, 0) >= 0)
+ if (prev_suspended && !prev_suspended)
+ pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0);
+ }
+ }
+
+ if (d->source_name) {
+ pa_source *source;
+
+ if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0)))
+ pa_source_suspend(source, 0);
+ }
+
+ } else
+ /* Yes, we don't check the UDI for validity, but hopefully HAL will */
+ device_added_cb(u->context, udi);
}
finish:
n = hal_device_add_all(u, CAPABILITY_ALSA);
#endif
#if defined(HAVE_ALSA) && defined(HAVE_OSS)
- if (n <= 0)
+ if (!u->capability)
#endif
#ifdef HAVE_OSS
n += hal_device_add_all(u, CAPABILITY_OSS);
pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message);
goto fail;
}
+
+ dbus_bus_add_match(pa_dbus_connection_get(conn), "type='signal',interface='org.pulseaudio.Server'", &error);
+ if (dbus_error_is_set(&error)) {
+ pa_log_error("Unable to subscribe to PulseAudio signals: %s: %s", error.name, error.message);
+ goto fail;
+ }
pa_log_info("Loaded %i modules.", n);