]> code.delx.au - pulseaudio/blob - src/modules/module-stream-restore.c
23f4780136900a6fdd6bc9526a82d8af1b192bd6
[pulseaudio] / src / modules / module-stream-restore.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2008 Lennart Poettering
5 Copyright 2009 Tanu Kaskinen
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <unistd.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <sys/types.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #include <pulse/gccmacro.h>
35 #include <pulse/xmalloc.h>
36 #include <pulse/volume.h>
37 #include <pulse/timeval.h>
38 #include <pulse/rtclock.h>
39
40 #include <pulsecore/core-error.h>
41 #include <pulsecore/module.h>
42 #include <pulsecore/core-util.h>
43 #include <pulsecore/modargs.h>
44 #include <pulsecore/log.h>
45 #include <pulsecore/core-subscribe.h>
46 #include <pulsecore/sink-input.h>
47 #include <pulsecore/source-output.h>
48 #include <pulsecore/namereg.h>
49 #include <pulsecore/protocol-native.h>
50 #include <pulsecore/pstream.h>
51 #include <pulsecore/pstream-util.h>
52 #include <pulsecore/database.h>
53 #include <pulsecore/tagstruct.h>
54 #include <pulsecore/proplist-util.h>
55
56 #ifdef HAVE_DBUS
57 #include <pulsecore/dbus-util.h>
58 #include <pulsecore/protocol-dbus.h>
59 #endif
60
61 #include "module-stream-restore-symdef.h"
62
63 PA_MODULE_AUTHOR("Lennart Poettering");
64 PA_MODULE_DESCRIPTION("Automatically restore the volume/mute/device state of streams");
65 PA_MODULE_VERSION(PACKAGE_VERSION);
66 PA_MODULE_LOAD_ONCE(TRUE);
67 PA_MODULE_USAGE(
68 "restore_device=<Save/restore sinks/sources?> "
69 "restore_volume=<Save/restore volumes?> "
70 "restore_muted=<Save/restore muted states?> "
71 "on_hotplug=<When new device becomes available, recheck streams?> "
72 "on_rescue=<When device becomes unavailable, recheck streams?> "
73 "fallback_table=<filename>");
74
75 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
76 #define IDENTIFICATION_PROPERTY "module-stream-restore.id"
77
78 #define DEFAULT_FALLBACK_FILE PA_DEFAULT_CONFIG_DIR"/stream-restore.table"
79 #define DEFAULT_FALLBACK_FILE_USER "stream-restore.table"
80
81 #define WHITESPACE "\n\r \t"
82
83 static const char* const valid_modargs[] = {
84 "restore_device",
85 "restore_volume",
86 "restore_muted",
87 "on_hotplug",
88 "on_rescue",
89 "fallback_table",
90 NULL
91 };
92
93 struct userdata {
94 pa_core *core;
95 pa_module *module;
96 pa_subscription *subscription;
97 pa_hook_slot
98 *sink_input_new_hook_slot,
99 *sink_input_fixate_hook_slot,
100 *source_output_new_hook_slot,
101 *source_output_fixate_hook_slot,
102 *sink_put_hook_slot,
103 *source_put_hook_slot,
104 *sink_unlink_hook_slot,
105 *source_unlink_hook_slot,
106 *connection_unlink_hook_slot;
107 pa_time_event *save_time_event;
108 pa_database* database;
109
110 pa_bool_t restore_device:1;
111 pa_bool_t restore_volume:1;
112 pa_bool_t restore_muted:1;
113 pa_bool_t on_hotplug:1;
114 pa_bool_t on_rescue:1;
115
116 pa_native_protocol *protocol;
117 pa_idxset *subscribed;
118
119 #ifdef HAVE_DBUS
120 pa_dbus_protocol *dbus_protocol;
121 pa_hashmap *dbus_entries;
122 uint32_t next_index; /* For generating object paths for entries. */
123 #endif
124 };
125
126 #define ENTRY_VERSION 1
127
128 struct entry {
129 uint8_t version;
130 pa_bool_t muted_valid, volume_valid, device_valid, card_valid;
131 pa_bool_t muted;
132 pa_channel_map channel_map;
133 pa_cvolume volume;
134 char* device;
135 char* card;
136 };
137
138 enum {
139 SUBCOMMAND_TEST,
140 SUBCOMMAND_READ,
141 SUBCOMMAND_WRITE,
142 SUBCOMMAND_DELETE,
143 SUBCOMMAND_SUBSCRIBE,
144 SUBCOMMAND_EVENT
145 };
146
147
148 static struct entry* entry_new(void);
149 static void entry_free(struct entry *e);
150 static struct entry *entry_read(struct userdata *u, const char *name);
151 static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e, pa_bool_t replace);
152 static struct entry* entry_copy(const struct entry *e);
153 static void entry_apply(struct userdata *u, const char *name, struct entry *e);
154 static void trigger_save(struct userdata *u);
155
156 #ifdef HAVE_DBUS
157
158 #define OBJECT_PATH "/org/pulseaudio/stream_restore1"
159 #define ENTRY_OBJECT_NAME "entry"
160 #define INTERFACE_STREAM_RESTORE "org.PulseAudio.Ext.StreamRestore1"
161 #define INTERFACE_ENTRY INTERFACE_STREAM_RESTORE ".RestoreEntry"
162
163 #define DBUS_INTERFACE_REVISION 0
164
165 struct dbus_entry {
166 struct userdata *userdata;
167
168 char *entry_name;
169 uint32_t index;
170 char *object_path;
171 };
172
173 static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata);
174 static void handle_get_entries(DBusConnection *conn, DBusMessage *msg, void *userdata);
175
176 static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
177
178 static void handle_add_entry(DBusConnection *conn, DBusMessage *msg, void *userdata);
179 static void handle_get_entry_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
180
181 static void handle_entry_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
182 static void handle_entry_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
183 static void handle_entry_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
184 static void handle_entry_set_device(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
185 static void handle_entry_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
186 static void handle_entry_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
187 static void handle_entry_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
188 static void handle_entry_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
189
190 static void handle_entry_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
191
192 static void handle_entry_remove(DBusConnection *conn, DBusMessage *msg, void *userdata);
193
194 enum property_handler_index {
195 PROPERTY_HANDLER_INTERFACE_REVISION,
196 PROPERTY_HANDLER_ENTRIES,
197 PROPERTY_HANDLER_MAX
198 };
199
200 enum entry_property_handler_index {
201 ENTRY_PROPERTY_HANDLER_INDEX,
202 ENTRY_PROPERTY_HANDLER_NAME,
203 ENTRY_PROPERTY_HANDLER_DEVICE,
204 ENTRY_PROPERTY_HANDLER_VOLUME,
205 ENTRY_PROPERTY_HANDLER_MUTE,
206 ENTRY_PROPERTY_HANDLER_MAX
207 };
208
209 static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
210 [PROPERTY_HANDLER_INTERFACE_REVISION] = { .property_name = "InterfaceRevision", .type = "u", .get_cb = handle_get_interface_revision, .set_cb = NULL },
211 [PROPERTY_HANDLER_ENTRIES] = { .property_name = "Entries", .type = "ao", .get_cb = handle_get_entries, .set_cb = NULL }
212 };
213
214 static pa_dbus_property_handler entry_property_handlers[ENTRY_PROPERTY_HANDLER_MAX] = {
215 [ENTRY_PROPERTY_HANDLER_INDEX] = { .property_name = "Index", .type = "u", .get_cb = handle_entry_get_index, .set_cb = NULL },
216 [ENTRY_PROPERTY_HANDLER_NAME] = { .property_name = "Name", .type = "s", .get_cb = handle_entry_get_name, .set_cb = NULL },
217 [ENTRY_PROPERTY_HANDLER_DEVICE] = { .property_name = "Device", .type = "s", .get_cb = handle_entry_get_device, .set_cb = handle_entry_set_device },
218 [ENTRY_PROPERTY_HANDLER_VOLUME] = { .property_name = "Volume", .type = "a(uu)", .get_cb = handle_entry_get_volume, .set_cb = handle_entry_set_volume },
219 [ENTRY_PROPERTY_HANDLER_MUTE] = { .property_name = "Mute", .type = "b", .get_cb = handle_entry_get_mute, .set_cb = handle_entry_set_mute }
220 };
221
222 enum method_handler_index {
223 METHOD_HANDLER_ADD_ENTRY,
224 METHOD_HANDLER_GET_ENTRY_BY_NAME,
225 METHOD_HANDLER_MAX
226 };
227
228 enum entry_method_handler_index {
229 ENTRY_METHOD_HANDLER_REMOVE,
230 ENTRY_METHOD_HANDLER_MAX
231 };
232
233 static pa_dbus_arg_info add_entry_args[] = { { "name", "s", "in" },
234 { "device", "s", "in" },
235 { "volume", "a(uu)", "in" },
236 { "mute", "b", "in" },
237 { "apply_immediately", "b", "in" },
238 { "entry", "o", "out" } };
239 static pa_dbus_arg_info get_entry_by_name_args[] = { { "name", "s", "in" }, { "entry", "o", "out" } };
240
241 static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
242 [METHOD_HANDLER_ADD_ENTRY] = {
243 .method_name = "AddEntry",
244 .arguments = add_entry_args,
245 .n_arguments = sizeof(add_entry_args) / sizeof(pa_dbus_arg_info),
246 .receive_cb = handle_add_entry },
247 [METHOD_HANDLER_GET_ENTRY_BY_NAME] = {
248 .method_name = "GetEntryByName",
249 .arguments = get_entry_by_name_args,
250 .n_arguments = sizeof(get_entry_by_name_args) / sizeof(pa_dbus_arg_info),
251 .receive_cb = handle_get_entry_by_name }
252 };
253
254 static pa_dbus_method_handler entry_method_handlers[ENTRY_METHOD_HANDLER_MAX] = {
255 [ENTRY_METHOD_HANDLER_REMOVE] = {
256 .method_name = "Remove",
257 .arguments = NULL,
258 .n_arguments = 0,
259 .receive_cb = handle_entry_remove }
260 };
261
262 enum signal_index {
263 SIGNAL_NEW_ENTRY,
264 SIGNAL_ENTRY_REMOVED,
265 SIGNAL_MAX
266 };
267
268 enum entry_signal_index {
269 ENTRY_SIGNAL_DEVICE_UPDATED,
270 ENTRY_SIGNAL_VOLUME_UPDATED,
271 ENTRY_SIGNAL_MUTE_UPDATED,
272 ENTRY_SIGNAL_MAX
273 };
274
275 static pa_dbus_arg_info new_entry_args[] = { { "entry", "o", NULL } };
276 static pa_dbus_arg_info entry_removed_args[] = { { "entry", "o", NULL } };
277
278 static pa_dbus_arg_info entry_device_updated_args[] = { { "device", "s", NULL } };
279 static pa_dbus_arg_info entry_volume_updated_args[] = { { "volume", "a(uu)", NULL } };
280 static pa_dbus_arg_info entry_mute_updated_args[] = { { "muted", "b", NULL } };
281
282 static pa_dbus_signal_info signals[SIGNAL_MAX] = {
283 [SIGNAL_NEW_ENTRY] = { .name = "NewEntry", .arguments = new_entry_args, .n_arguments = 1 },
284 [SIGNAL_ENTRY_REMOVED] = { .name = "EntryRemoved", .arguments = entry_removed_args, .n_arguments = 1 }
285 };
286
287 static pa_dbus_signal_info entry_signals[ENTRY_SIGNAL_MAX] = {
288 [ENTRY_SIGNAL_DEVICE_UPDATED] = { .name = "DeviceUpdated", .arguments = entry_device_updated_args, .n_arguments = 1 },
289 [ENTRY_SIGNAL_VOLUME_UPDATED] = { .name = "VolumeUpdated", .arguments = entry_volume_updated_args, .n_arguments = 1 },
290 [ENTRY_SIGNAL_MUTE_UPDATED] = { .name = "MuteUpdated", .arguments = entry_mute_updated_args, .n_arguments = 1 }
291 };
292
293 static pa_dbus_interface_info stream_restore_interface_info = {
294 .name = INTERFACE_STREAM_RESTORE,
295 .method_handlers = method_handlers,
296 .n_method_handlers = METHOD_HANDLER_MAX,
297 .property_handlers = property_handlers,
298 .n_property_handlers = PROPERTY_HANDLER_MAX,
299 .get_all_properties_cb = handle_get_all,
300 .signals = signals,
301 .n_signals = SIGNAL_MAX
302 };
303
304 static pa_dbus_interface_info entry_interface_info = {
305 .name = INTERFACE_ENTRY,
306 .method_handlers = entry_method_handlers,
307 .n_method_handlers = ENTRY_METHOD_HANDLER_MAX,
308 .property_handlers = entry_property_handlers,
309 .n_property_handlers = ENTRY_PROPERTY_HANDLER_MAX,
310 .get_all_properties_cb = handle_entry_get_all,
311 .signals = entry_signals,
312 .n_signals = ENTRY_SIGNAL_MAX
313 };
314
315 static struct dbus_entry *dbus_entry_new(struct userdata *u, const char *entry_name) {
316 struct dbus_entry *de;
317
318 pa_assert(u);
319 pa_assert(entry_name);
320 pa_assert(*entry_name);
321
322 de = pa_xnew(struct dbus_entry, 1);
323 de->userdata = u;
324 de->entry_name = pa_xstrdup(entry_name);
325 de->index = u->next_index++;
326 de->object_path = pa_sprintf_malloc("%s/%s%u", OBJECT_PATH, ENTRY_OBJECT_NAME, de->index);
327
328 pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, de->object_path, &entry_interface_info, de) >= 0);
329
330 return de;
331 }
332
333 static void dbus_entry_free(struct dbus_entry *de) {
334 pa_assert(de);
335
336 pa_assert_se(pa_dbus_protocol_remove_interface(de->userdata->dbus_protocol, de->object_path, entry_interface_info.name) >= 0);
337
338 pa_xfree(de->entry_name);
339 pa_xfree(de->object_path);
340 pa_xfree(de);
341 }
342
343 /* Reads an array [(UInt32, UInt32)] from the iterator. The struct items are
344 * are a channel position and a volume value, respectively. The result is
345 * stored in the map and vol arguments. The iterator must point to a "a(uu)"
346 * element. If the data is invalid, an error reply is sent and a negative
347 * number is returned. In case of a failure we make no guarantees about the
348 * state of map and vol. In case of an empty array the channels field of both
349 * map and vol are set to 0. This function calls dbus_message_iter_next(iter)
350 * before returning. */
351 static int get_volume_arg(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, pa_channel_map *map, pa_cvolume *vol) {
352 DBusMessageIter array_iter;
353 DBusMessageIter struct_iter;
354
355 pa_assert(conn);
356 pa_assert(msg);
357 pa_assert(iter);
358 pa_assert(pa_streq(dbus_message_iter_get_signature(iter), "a(uu)"));
359 pa_assert(map);
360 pa_assert(vol);
361
362 pa_channel_map_init(map);
363 pa_cvolume_init(vol);
364
365 map->channels = 0;
366 vol->channels = 0;
367
368 dbus_message_iter_recurse(iter, &array_iter);
369
370 while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) {
371 dbus_uint32_t chan_pos;
372 dbus_uint32_t chan_vol;
373
374 dbus_message_iter_recurse(&array_iter, &struct_iter);
375
376 dbus_message_iter_get_basic(&struct_iter, &chan_pos);
377
378 if (chan_pos >= PA_CHANNEL_POSITION_MAX) {
379 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position: %u", chan_pos);
380 return -1;
381 }
382
383 pa_assert_se(dbus_message_iter_next(&struct_iter));
384 dbus_message_iter_get_basic(&struct_iter, &chan_vol);
385
386 if (!PA_VOLUME_IS_VALID(chan_vol)) {
387 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u", chan_vol);
388 return -1;
389 }
390
391 if (map->channels < PA_CHANNELS_MAX) {
392 map->map[map->channels] = chan_pos;
393 vol->values[map->channels] = chan_vol;
394 }
395 ++map->channels;
396 ++vol->channels;
397
398 dbus_message_iter_next(&array_iter);
399 }
400
401 if (map->channels > PA_CHANNELS_MAX) {
402 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too many channels: %u. The maximum is %u.", map->channels, PA_CHANNELS_MAX);
403 return -1;
404 }
405
406 dbus_message_iter_next(iter);
407
408 return 0;
409 }
410
411 static void append_volume(DBusMessageIter *iter, struct entry *e) {
412 DBusMessageIter array_iter;
413 DBusMessageIter struct_iter;
414 unsigned i;
415
416 pa_assert(iter);
417 pa_assert(e);
418
419 pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(uu)", &array_iter));
420
421 if (!e->volume_valid) {
422 pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
423 return;
424 }
425
426 for (i = 0; i < e->channel_map.channels; ++i) {
427 pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter));
428
429 pa_assert_se(dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &e->channel_map.map[i]));
430 pa_assert_se(dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &e->volume.values[i]));
431
432 pa_assert_se(dbus_message_iter_close_container(&array_iter, &struct_iter));
433 }
434
435 pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
436 }
437
438 static void append_volume_variant(DBusMessageIter *iter, struct entry *e) {
439 DBusMessageIter variant_iter;
440
441 pa_assert(iter);
442 pa_assert(e);
443
444 pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(uu)", &variant_iter));
445
446 append_volume(&variant_iter, e);
447
448 pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
449 }
450
451 static void send_new_entry_signal(struct dbus_entry *entry) {
452 DBusMessage *signal_msg;
453
454 pa_assert(entry);
455
456 pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_NEW_ENTRY].name));
457 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID));
458 pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal_msg);
459 dbus_message_unref(signal_msg);
460 }
461
462 static void send_entry_removed_signal(struct dbus_entry *entry) {
463 DBusMessage *signal_msg;
464
465 pa_assert(entry);
466
467 pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_ENTRY_REMOVED].name));
468 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID));
469 pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal_msg);
470 dbus_message_unref(signal_msg);
471 }
472
473 static void send_device_updated_signal(struct dbus_entry *de, struct entry *e) {
474 DBusMessage *signal_msg;
475 const char *device;
476
477 pa_assert(de);
478 pa_assert(e);
479
480 device = e->device_valid ? e->device : "";
481
482 pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_DEVICE_UPDATED].name));
483 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID));
484 pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg);
485 dbus_message_unref(signal_msg);
486 }
487
488 static void send_volume_updated_signal(struct dbus_entry *de, struct entry *e) {
489 DBusMessage *signal_msg;
490 DBusMessageIter msg_iter;
491
492 pa_assert(de);
493 pa_assert(e);
494
495 pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_VOLUME_UPDATED].name));
496 dbus_message_iter_init_append(signal_msg, &msg_iter);
497 append_volume(&msg_iter, e);
498 pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg);
499 dbus_message_unref(signal_msg);
500 }
501
502 static void send_mute_updated_signal(struct dbus_entry *de, struct entry *e) {
503 DBusMessage *signal_msg;
504 dbus_bool_t muted;
505
506 pa_assert(de);
507 pa_assert(e);
508
509 pa_assert(e->muted_valid);
510
511 muted = e->muted;
512
513 pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_MUTE_UPDATED].name));
514 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &muted, DBUS_TYPE_INVALID));
515 pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg);
516 dbus_message_unref(signal_msg);
517 }
518
519 static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata) {
520 dbus_uint32_t interface_revision = DBUS_INTERFACE_REVISION;
521
522 pa_assert(conn);
523 pa_assert(msg);
524
525 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &interface_revision);
526 }
527
528 /* The caller frees the array, but not the strings. */
529 static const char **get_entries(struct userdata *u, unsigned *n) {
530 const char **entries;
531 unsigned i = 0;
532 void *state = NULL;
533 struct dbus_entry *de;
534
535 pa_assert(u);
536 pa_assert(n);
537
538 *n = pa_hashmap_size(u->dbus_entries);
539
540 if (*n == 0)
541 return NULL;
542
543 entries = pa_xnew(const char *, *n);
544
545 PA_HASHMAP_FOREACH(de, u->dbus_entries, state)
546 entries[i++] = de->object_path;
547
548 return entries;
549 }
550
551 static void handle_get_entries(DBusConnection *conn, DBusMessage *msg, void *userdata) {
552 struct userdata *u = userdata;
553 const char **entries;
554 unsigned n;
555
556 pa_assert(conn);
557 pa_assert(msg);
558 pa_assert(u);
559
560 entries = get_entries(u, &n);
561
562 pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, entries, n);
563
564 pa_xfree(entries);
565 }
566
567 static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
568 struct userdata *u = userdata;
569 DBusMessage *reply = NULL;
570 DBusMessageIter msg_iter;
571 DBusMessageIter dict_iter;
572 dbus_uint32_t interface_revision;
573 const char **entries;
574 unsigned n_entries;
575
576 pa_assert(conn);
577 pa_assert(msg);
578 pa_assert(u);
579
580 interface_revision = DBUS_INTERFACE_REVISION;
581 entries = get_entries(u, &n_entries);
582
583 pa_assert_se((reply = dbus_message_new_method_return(msg)));
584
585 dbus_message_iter_init_append(reply, &msg_iter);
586 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
587
588 pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INTERFACE_REVISION].property_name, DBUS_TYPE_UINT32, &interface_revision);
589 pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ENTRIES].property_name, DBUS_TYPE_OBJECT_PATH, entries, n_entries);
590
591 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
592
593 pa_assert_se(dbus_connection_send(conn, reply, NULL));
594
595 dbus_message_unref(reply);
596
597 pa_xfree(entries);
598 }
599
600 static void handle_add_entry(DBusConnection *conn, DBusMessage *msg, void *userdata) {
601 struct userdata *u = userdata;
602 DBusMessageIter msg_iter;
603 const char *name = NULL;
604 const char *device = NULL;
605 pa_channel_map map;
606 pa_cvolume vol;
607 dbus_bool_t muted = FALSE;
608 dbus_bool_t apply_immediately = FALSE;
609 struct dbus_entry *dbus_entry = NULL;
610 struct entry *e = NULL;
611
612 pa_assert(conn);
613 pa_assert(msg);
614 pa_assert(u);
615
616 pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
617 dbus_message_iter_get_basic(&msg_iter, &name);
618
619 pa_assert_se(dbus_message_iter_next(&msg_iter));
620 dbus_message_iter_get_basic(&msg_iter, &device);
621
622 pa_assert_se(dbus_message_iter_next(&msg_iter));
623 if (get_volume_arg(conn, msg, &msg_iter, &map, &vol) < 0)
624 return;
625
626 dbus_message_iter_get_basic(&msg_iter, &muted);
627
628 pa_assert_se(dbus_message_iter_next(&msg_iter));
629 dbus_message_iter_get_basic(&msg_iter, &apply_immediately);
630
631 if (!*name) {
632 pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "An empty string was given as the entry name.");
633 return;
634 }
635
636 if ((dbus_entry = pa_hashmap_get(u->dbus_entries, name))) {
637 pa_bool_t mute_updated = FALSE;
638 pa_bool_t volume_updated = FALSE;
639 pa_bool_t device_updated = FALSE;
640
641 pa_assert_se(e = entry_read(u, name));
642 mute_updated = e->muted != muted;
643 e->muted = muted;
644 e->muted_valid = TRUE;
645
646 volume_updated = (e->volume_valid != !!map.channels) || !pa_cvolume_equal(&e->volume, &vol);
647 e->volume = vol;
648 e->channel_map = map;
649 e->volume_valid = !!map.channels;
650
651 device_updated = (e->device_valid != !!device[0]) || !pa_streq(e->device, device);
652 pa_xfree(e->device);
653 e->device = pa_xstrdup(device);
654 e->device_valid = !!device[0];
655
656 if (mute_updated)
657 send_mute_updated_signal(dbus_entry, e);
658 if (volume_updated)
659 send_volume_updated_signal(dbus_entry, e);
660 if (device_updated)
661 send_device_updated_signal(dbus_entry, e);
662
663 } else {
664 dbus_entry = dbus_entry_new(u, name);
665 pa_assert_se(pa_hashmap_put(u->dbus_entries, dbus_entry->entry_name, dbus_entry) == 0);
666
667 e = entry_new();
668 e->muted_valid = TRUE;
669 e->volume_valid = !!map.channels;
670 e->device_valid = !!device[0];
671 e->muted = muted;
672 e->volume = vol;
673 e->channel_map = map;
674 e->device = pa_xstrdup(device);
675
676 send_new_entry_signal(dbus_entry);
677 }
678
679 pa_assert_se(entry_write(u, name, e, TRUE));
680
681 if (apply_immediately)
682 entry_apply(u, name, e);
683
684 trigger_save(u);
685
686 pa_dbus_send_empty_reply(conn, msg);
687
688 entry_free(e);
689 }
690
691 static void handle_get_entry_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
692 struct userdata *u = userdata;
693 const char *name;
694 struct dbus_entry *de;
695
696 pa_assert(conn);
697 pa_assert(msg);
698 pa_assert(u);
699
700 pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID));
701
702 if (!(de = pa_hashmap_get(u->dbus_entries, name))) {
703 pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such stream restore entry.");
704 return;
705 }
706
707 pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &de->object_path);
708 }
709
710 static void handle_entry_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
711 struct dbus_entry *de = userdata;
712
713 pa_assert(conn);
714 pa_assert(msg);
715 pa_assert(de);
716
717 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &de->index);
718 }
719
720 static void handle_entry_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
721 struct dbus_entry *de = userdata;
722
723 pa_assert(conn);
724 pa_assert(msg);
725 pa_assert(de);
726
727 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &de->entry_name);
728 }
729
730 static void handle_entry_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
731 struct dbus_entry *de = userdata;
732 struct entry *e;
733 const char *device;
734
735 pa_assert(conn);
736 pa_assert(msg);
737 pa_assert(de);
738
739 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
740
741 device = e->device_valid ? e->device : "";
742
743 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &device);
744
745 entry_free(e);
746 }
747
748 static void handle_entry_set_device(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
749 struct dbus_entry *de = userdata;
750 const char *device;
751 struct entry *e;
752 pa_bool_t updated;
753
754 pa_assert(conn);
755 pa_assert(msg);
756 pa_assert(iter);
757 pa_assert(de);
758
759 dbus_message_iter_get_basic(iter, &device);
760
761 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
762
763 updated = (e->device_valid != !!device[0]) || !pa_streq(e->device, device);
764
765 if (updated) {
766 pa_xfree(e->device);
767 e->device = pa_xstrdup(device);
768 e->device_valid = !!device[0];
769
770 pa_assert_se(entry_write(de->userdata, de->entry_name, e, TRUE));
771
772 entry_apply(de->userdata, de->entry_name, e);
773 send_device_updated_signal(de, e);
774 trigger_save(de->userdata);
775 }
776
777 pa_dbus_send_empty_reply(conn, msg);
778
779 entry_free(e);
780 }
781
782 static void handle_entry_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
783 struct dbus_entry *de = userdata;
784 DBusMessage *reply;
785 DBusMessageIter msg_iter;
786 struct entry *e;
787
788 pa_assert(conn);
789 pa_assert(msg);
790 pa_assert(de);
791
792 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
793
794 pa_assert_se(reply = dbus_message_new_method_return(msg));
795
796 dbus_message_iter_init_append(reply, &msg_iter);
797 append_volume_variant(&msg_iter, e);
798
799 pa_assert_se(dbus_connection_send(conn, reply, NULL));
800
801 entry_free(e);
802 }
803
804 static void handle_entry_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
805 struct dbus_entry *de = userdata;
806 pa_channel_map map;
807 pa_cvolume vol;
808 struct entry *e = NULL;
809 pa_bool_t updated = FALSE;
810
811 pa_assert(conn);
812 pa_assert(msg);
813 pa_assert(iter);
814 pa_assert(de);
815
816 if (get_volume_arg(conn, msg, iter, &map, &vol) < 0)
817 return;
818
819 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
820
821 updated = (e->volume_valid != !!map.channels) || !pa_cvolume_equal(&e->volume, &vol);
822
823 if (updated) {
824 e->volume = vol;
825 e->channel_map = map;
826 e->volume_valid = !!map.channels;
827
828 pa_assert_se(entry_write(de->userdata, de->entry_name, e, TRUE));
829
830 entry_apply(de->userdata, de->entry_name, e);
831 send_volume_updated_signal(de, e);
832 trigger_save(de->userdata);
833 }
834
835 pa_dbus_send_empty_reply(conn, msg);
836
837 entry_free(e);
838 }
839
840 static void handle_entry_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
841 struct dbus_entry *de = userdata;
842 struct entry *e;
843 dbus_bool_t mute;
844
845 pa_assert(conn);
846 pa_assert(msg);
847 pa_assert(de);
848
849 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
850
851 mute = e->muted_valid ? e->muted : FALSE;
852
853 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &mute);
854
855 entry_free(e);
856 }
857
858 static void handle_entry_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
859 struct dbus_entry *de = userdata;
860 dbus_bool_t mute;
861 struct entry *e;
862 pa_bool_t updated;
863
864 pa_assert(conn);
865 pa_assert(msg);
866 pa_assert(iter);
867 pa_assert(de);
868
869 dbus_message_iter_get_basic(iter, &mute);
870
871 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
872
873 updated = !e->muted_valid || e->muted != mute;
874
875 if (updated) {
876 e->muted = mute;
877 e->muted_valid = TRUE;
878
879 pa_assert_se(entry_write(de->userdata, de->entry_name, e, TRUE));
880
881 entry_apply(de->userdata, de->entry_name, e);
882 send_mute_updated_signal(de, e);
883 trigger_save(de->userdata);
884 }
885
886 pa_dbus_send_empty_reply(conn, msg);
887
888 entry_free(e);
889 }
890
891 static void handle_entry_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
892 struct dbus_entry *de = userdata;
893 struct entry *e;
894 DBusMessage *reply = NULL;
895 DBusMessageIter msg_iter;
896 DBusMessageIter dict_iter;
897 DBusMessageIter dict_entry_iter;
898 const char *device;
899 dbus_bool_t mute;
900
901 pa_assert(conn);
902 pa_assert(msg);
903 pa_assert(de);
904
905 pa_assert_se(e = entry_read(de->userdata, de->entry_name));
906
907 device = e->device_valid ? e->device : "";
908 mute = e->muted_valid ? e->muted : FALSE;
909
910 pa_assert_se((reply = dbus_message_new_method_return(msg)));
911
912 dbus_message_iter_init_append(reply, &msg_iter);
913 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
914
915 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &de->index);
916 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &de->entry_name);
917 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_DEVICE].property_name, DBUS_TYPE_STRING, &device);
918
919 pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
920
921 pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &entry_property_handlers[ENTRY_PROPERTY_HANDLER_VOLUME].property_name));
922 append_volume_variant(&dict_entry_iter, e);
923
924 pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
925
926 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &mute);
927
928 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
929
930 pa_assert_se(dbus_connection_send(conn, reply, NULL));
931
932 dbus_message_unref(reply);
933
934 entry_free(e);
935 }
936
937 static void handle_entry_remove(DBusConnection *conn, DBusMessage *msg, void *userdata) {
938 struct dbus_entry *de = userdata;
939 pa_datum key;
940
941 pa_assert(conn);
942 pa_assert(msg);
943 pa_assert(de);
944
945 key.data = de->entry_name;
946 key.size = strlen(de->entry_name);
947
948 pa_assert_se(pa_database_unset(de->userdata->database, &key) == 0);
949
950 send_entry_removed_signal(de);
951 trigger_save(de->userdata);
952
953 pa_assert_se(pa_hashmap_remove(de->userdata->dbus_entries, de->entry_name));
954 dbus_entry_free(de);
955
956 pa_dbus_send_empty_reply(conn, msg);
957 }
958
959 #endif /* HAVE_DBUS */
960
961 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
962 struct userdata *u = userdata;
963
964 pa_assert(a);
965 pa_assert(e);
966 pa_assert(u);
967
968 pa_assert(e == u->save_time_event);
969 u->core->mainloop->time_free(u->save_time_event);
970 u->save_time_event = NULL;
971
972 pa_database_sync(u->database);
973 pa_log_info("Synced.");
974 }
975
976 static struct entry* entry_new(void) {
977 struct entry *r = pa_xnew0(struct entry, 1);
978 r->version = ENTRY_VERSION;
979 return r;
980 }
981
982 static void entry_free(struct entry* e) {
983 pa_assert(e);
984
985 pa_xfree(e->device);
986 pa_xfree(e->card);
987 pa_xfree(e);
988 }
989
990 static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e, pa_bool_t replace) {
991 pa_tagstruct *t;
992 pa_datum key, data;
993 pa_bool_t r;
994
995 pa_assert(u);
996 pa_assert(name);
997 pa_assert(e);
998
999 t = pa_tagstruct_new(NULL, 0);
1000 pa_tagstruct_putu8(t, e->version);
1001 pa_tagstruct_put_boolean(t, e->volume_valid);
1002 pa_tagstruct_put_channel_map(t, &e->channel_map);
1003 pa_tagstruct_put_cvolume(t, &e->volume);
1004 pa_tagstruct_put_boolean(t, e->muted_valid);
1005 pa_tagstruct_put_boolean(t, e->muted);
1006 pa_tagstruct_put_boolean(t, e->device_valid);
1007 pa_tagstruct_puts(t, e->device);
1008 pa_tagstruct_put_boolean(t, e->card_valid);
1009 pa_tagstruct_puts(t, e->card);
1010
1011 key.data = (char *) name;
1012 key.size = strlen(name);
1013
1014 data.data = (void*)pa_tagstruct_data(t, &data.size);
1015
1016 r = (pa_database_set(u->database, &key, &data, replace) == 0);
1017
1018 pa_tagstruct_free(t);
1019
1020 return r;
1021 }
1022
1023 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
1024
1025 #define LEGACY_ENTRY_VERSION 3
1026 static struct entry *legacy_entry_read(struct userdata *u, const char *name) {
1027 struct legacy_entry {
1028 uint8_t version;
1029 pa_bool_t muted_valid:1, volume_valid:1, device_valid:1, card_valid:1;
1030 pa_bool_t muted:1;
1031 pa_channel_map channel_map;
1032 pa_cvolume volume;
1033 char device[PA_NAME_MAX];
1034 char card[PA_NAME_MAX];
1035 } PA_GCC_PACKED;
1036
1037 pa_datum key;
1038 pa_datum data;
1039 struct legacy_entry *le;
1040 struct entry *e;
1041
1042 pa_assert(u);
1043 pa_assert(name);
1044
1045 key.data = (char *) name;
1046 key.size = strlen(name);
1047
1048 pa_zero(data);
1049
1050 if (!pa_database_get(u->database, &key, &data))
1051 goto fail;
1052
1053 if (data.size != sizeof(struct legacy_entry)) {
1054 pa_log_debug("Size does not match.");
1055 goto fail;
1056 }
1057
1058 le = (struct legacy_entry *) data.data;
1059
1060 if (le->version != LEGACY_ENTRY_VERSION) {
1061 pa_log_debug("Version mismatch.");
1062 goto fail;
1063 }
1064
1065 if (!memchr(le->device, 0, sizeof(le->device))) {
1066 pa_log_warn("Device has missing NUL byte.");
1067 goto fail;
1068 }
1069
1070 if (!memchr(le->card, 0, sizeof(le->card))) {
1071 pa_log_warn("Card has missing NUL byte.");
1072 goto fail;
1073 }
1074
1075 if (le->device_valid && !pa_namereg_is_valid_name(le->device)) {
1076 pa_log_warn("Invalid device name stored in database for legacy stream");
1077 goto fail;
1078 }
1079
1080 if (le->card_valid && !pa_namereg_is_valid_name(le->card)) {
1081 pa_log_warn("Invalid card name stored in database for legacy stream");
1082 goto fail;
1083 }
1084
1085 if (le->volume_valid && !pa_channel_map_valid(&le->channel_map)) {
1086 pa_log_warn("Invalid channel map stored in database for legacy stream");
1087 goto fail;
1088 }
1089
1090 if (le->volume_valid && (!pa_cvolume_valid(&le->volume) || !pa_cvolume_compatible_with_channel_map(&le->volume, &le->channel_map))) {
1091 pa_log_warn("Invalid volume stored in database for legacy stream");
1092 goto fail;
1093 }
1094
1095 e = entry_new();
1096 e->muted_valid = le->muted_valid;
1097 e->muted = le->muted;
1098 e->volume_valid = le->volume_valid;
1099 e->channel_map = le->channel_map;
1100 e->volume = le->volume;
1101 e->device_valid = le->device_valid;
1102 e->device = pa_xstrdup(le->device);
1103 e->card_valid = le->card_valid;
1104 e->card = pa_xstrdup(le->card);
1105 return e;
1106
1107 fail:
1108 pa_datum_free(&data);
1109
1110 return NULL;
1111 }
1112 #endif
1113
1114 static struct entry *entry_read(struct userdata *u, const char *name) {
1115 pa_datum key, data;
1116 struct entry *e = NULL;
1117 pa_tagstruct *t = NULL;
1118 const char *device, *card;
1119
1120 pa_assert(u);
1121 pa_assert(name);
1122
1123 key.data = (char*) name;
1124 key.size = strlen(name);
1125
1126 pa_zero(data);
1127
1128 if (!pa_database_get(u->database, &key, &data))
1129 goto fail;
1130
1131 t = pa_tagstruct_new(data.data, data.size);
1132 e = entry_new();
1133
1134 if (pa_tagstruct_getu8(t, &e->version) < 0 ||
1135 e->version > ENTRY_VERSION ||
1136 pa_tagstruct_get_boolean(t, &e->volume_valid) < 0 ||
1137 pa_tagstruct_get_channel_map(t, &e->channel_map) < 0 ||
1138 pa_tagstruct_get_cvolume(t, &e->volume) < 0 ||
1139 pa_tagstruct_get_boolean(t, &e->muted_valid) < 0 ||
1140 pa_tagstruct_get_boolean(t, &e->muted) < 0 ||
1141 pa_tagstruct_get_boolean(t, &e->device_valid) < 0 ||
1142 pa_tagstruct_gets(t, &device) < 0 ||
1143 pa_tagstruct_get_boolean(t, &e->card_valid) < 0 ||
1144 pa_tagstruct_gets(t, &card) < 0) {
1145
1146 goto fail;
1147 }
1148
1149 e->device = pa_xstrdup(device);
1150 e->card = pa_xstrdup(card);
1151
1152 if (!pa_tagstruct_eof(t))
1153 goto fail;
1154
1155 if (e->device_valid && !pa_namereg_is_valid_name(e->device)) {
1156 pa_log_warn("Invalid device name stored in database for stream %s", name);
1157 goto fail;
1158 }
1159
1160 if (e->card_valid && !pa_namereg_is_valid_name(e->card)) {
1161 pa_log_warn("Invalid card name stored in database for stream %s", name);
1162 goto fail;
1163 }
1164
1165 if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
1166 pa_log_warn("Invalid channel map stored in database for stream %s", name);
1167 goto fail;
1168 }
1169
1170 if (e->volume_valid && (!pa_cvolume_valid(&e->volume) || !pa_cvolume_compatible_with_channel_map(&e->volume, &e->channel_map))) {
1171 pa_log_warn("Invalid volume stored in database for stream %s", name);
1172 goto fail;
1173 }
1174
1175 pa_tagstruct_free(t);
1176 pa_datum_free(&data);
1177
1178 return e;
1179
1180 fail:
1181 if (e)
1182 entry_free(e);
1183 if (t)
1184 pa_tagstruct_free(t);
1185
1186 pa_datum_free(&data);
1187 return NULL;
1188 }
1189
1190 static struct entry* entry_copy(const struct entry *e) {
1191 struct entry* r;
1192
1193 pa_assert(e);
1194 r = entry_new();
1195 *r = *e;
1196 r->device = pa_xstrdup(e->device);
1197 r->card = pa_xstrdup(e->card);
1198 return r;
1199 }
1200
1201 static void trigger_save(struct userdata *u) {
1202 pa_native_connection *c;
1203 uint32_t idx;
1204
1205 PA_IDXSET_FOREACH(c, u->subscribed, idx) {
1206 pa_tagstruct *t;
1207
1208 t = pa_tagstruct_new(NULL, 0);
1209 pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
1210 pa_tagstruct_putu32(t, 0);
1211 pa_tagstruct_putu32(t, u->module->index);
1212 pa_tagstruct_puts(t, u->module->name);
1213 pa_tagstruct_putu32(t, SUBCOMMAND_EVENT);
1214
1215 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t);
1216 }
1217
1218 if (u->save_time_event)
1219 return;
1220
1221 u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
1222 }
1223
1224 static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
1225 pa_cvolume t;
1226
1227 pa_assert(a);
1228 pa_assert(b);
1229
1230 if (a->device_valid != b->device_valid ||
1231 (a->device_valid && !pa_streq(a->device, b->device)))
1232 return FALSE;
1233
1234 if (a->card_valid != b->card_valid ||
1235 (a->card_valid && !pa_streq(a->card, b->card)))
1236 return FALSE;
1237
1238 if (a->muted_valid != b->muted_valid ||
1239 (a->muted_valid && (a->muted != b->muted)))
1240 return FALSE;
1241
1242 t = b->volume;
1243 if (a->volume_valid != b->volume_valid ||
1244 (a->volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->volume)))
1245 return FALSE;
1246
1247 return TRUE;
1248 }
1249
1250 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
1251 struct userdata *u = userdata;
1252 struct entry *entry, *old = NULL;
1253 char *name = NULL;
1254
1255 /* These are only used when D-Bus is enabled, but in order to reduce ifdef
1256 * clutter these are defined here unconditionally. */
1257 pa_bool_t created_new_entry = TRUE;
1258 pa_bool_t device_updated = FALSE;
1259 pa_bool_t volume_updated = FALSE;
1260 pa_bool_t mute_updated = FALSE;
1261
1262 #ifdef HAVE_DBUS
1263 struct dbus_entry *de = NULL;
1264 #endif
1265
1266 pa_assert(c);
1267 pa_assert(u);
1268
1269 if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW) &&
1270 t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) &&
1271 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW) &&
1272 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
1273 return;
1274
1275 if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
1276 pa_sink_input *sink_input;
1277
1278 if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx)))
1279 return;
1280
1281 if (!(name = pa_proplist_get_stream_group(sink_input->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1282 return;
1283
1284 if ((old = entry_read(u, name))) {
1285 entry = entry_copy(old);
1286 created_new_entry = FALSE;
1287 } else
1288 entry = entry_new();
1289
1290 if (sink_input->save_volume && pa_sink_input_is_volume_readable(sink_input)) {
1291 pa_assert(sink_input->volume_writable);
1292
1293 entry->channel_map = sink_input->channel_map;
1294 pa_sink_input_get_volume(sink_input, &entry->volume, FALSE);
1295 entry->volume_valid = TRUE;
1296
1297 volume_updated = !created_new_entry
1298 && (!old->volume_valid
1299 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map)
1300 || !pa_cvolume_equal(&entry->volume, &old->volume));
1301 }
1302
1303 if (sink_input->save_muted) {
1304 entry->muted = pa_sink_input_get_mute(sink_input);
1305 entry->muted_valid = TRUE;
1306
1307 mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
1308 }
1309
1310 if (sink_input->save_sink) {
1311 pa_xfree(entry->device);
1312 entry->device = pa_xstrdup(sink_input->sink->name);
1313 entry->device_valid = TRUE;
1314
1315 device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
1316 if (sink_input->sink->card) {
1317 pa_xfree(entry->card);
1318 entry->card = pa_xstrdup(sink_input->sink->card->name);
1319 entry->card_valid = TRUE;
1320 }
1321 }
1322
1323 } else {
1324 pa_source_output *source_output;
1325
1326 pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT);
1327
1328 if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx)))
1329 return;
1330
1331 if (!(name = pa_proplist_get_stream_group(source_output->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1332 return;
1333
1334 if ((old = entry_read(u, name))) {
1335 entry = entry_copy(old);
1336 created_new_entry = FALSE;
1337 } else
1338 entry = entry_new();
1339
1340 if (source_output->save_volume && pa_source_output_is_volume_readable(source_output)) {
1341 pa_assert(source_output->volume_writable);
1342
1343 entry->channel_map = source_output->channel_map;
1344 pa_source_output_get_volume(source_output, &entry->volume, FALSE);
1345 entry->volume_valid = TRUE;
1346
1347 volume_updated = !created_new_entry
1348 && (!old->volume_valid
1349 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map)
1350 || !pa_cvolume_equal(&entry->volume, &old->volume));
1351 }
1352
1353 if (source_output->save_muted) {
1354 entry->muted = pa_source_output_get_mute(source_output);
1355 entry->muted_valid = TRUE;
1356
1357 mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
1358 }
1359
1360 if (source_output->save_source) {
1361 pa_xfree(entry->device);
1362 entry->device = pa_xstrdup(source_output->source->name);
1363 entry->device_valid = TRUE;
1364
1365 device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
1366
1367 if (source_output->source->card) {
1368 pa_xfree(entry->card);
1369 entry->card = pa_xstrdup(source_output->source->card->name);
1370 entry->card_valid = TRUE;
1371 }
1372 }
1373 }
1374
1375 pa_assert(entry);
1376
1377 if (old) {
1378
1379 if (entries_equal(old, entry)) {
1380 entry_free(old);
1381 entry_free(entry);
1382 pa_xfree(name);
1383 return;
1384 }
1385
1386 entry_free(old);
1387 }
1388
1389 pa_log_info("Storing volume/mute/device for stream %s.", name);
1390
1391 if (entry_write(u, name, entry, TRUE))
1392 trigger_save(u);
1393
1394 #ifdef HAVE_DBUS
1395 if (created_new_entry) {
1396 de = dbus_entry_new(u, name);
1397 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
1398 send_new_entry_signal(de);
1399 } else {
1400 pa_assert_se(de = pa_hashmap_get(u->dbus_entries, name));
1401
1402 if (device_updated)
1403 send_device_updated_signal(de, entry);
1404 if (volume_updated)
1405 send_volume_updated_signal(de, entry);
1406 if (mute_updated)
1407 send_mute_updated_signal(de, entry);
1408 }
1409 #endif
1410
1411 entry_free(entry);
1412 pa_xfree(name);
1413 }
1414
1415 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1416 char *name;
1417 struct entry *e;
1418
1419 pa_assert(c);
1420 pa_assert(new_data);
1421 pa_assert(u);
1422 pa_assert(u->restore_device);
1423
1424 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1425 return PA_HOOK_OK;
1426
1427 if (new_data->sink)
1428 pa_log_debug("Not restoring device for stream %s, because already set to '%s'.", name, new_data->sink->name);
1429 else if ((e = entry_read(u, name))) {
1430 pa_sink *s = NULL;
1431
1432 if (e->device_valid)
1433 s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK);
1434
1435 if (!s && e->card_valid) {
1436 pa_card *card;
1437
1438 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1439 s = pa_idxset_first(card->sinks, NULL);
1440 }
1441
1442 /* It might happen that a stream and a sink are set up at the
1443 same time, in which case we want to make sure we don't
1444 interfere with that */
1445 if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s)))
1446 if (pa_sink_input_new_data_set_sink(new_data, s, TRUE))
1447 pa_log_info("Restoring device for stream %s.", name);
1448
1449 entry_free(e);
1450 }
1451
1452 pa_xfree(name);
1453
1454 return PA_HOOK_OK;
1455 }
1456
1457 static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1458 char *name;
1459 struct entry *e;
1460
1461 pa_assert(c);
1462 pa_assert(new_data);
1463 pa_assert(u);
1464 pa_assert(u->restore_volume || u->restore_muted);
1465
1466 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1467 return PA_HOOK_OK;
1468
1469 if ((e = entry_read(u, name))) {
1470
1471 if (u->restore_volume && e->volume_valid) {
1472 if (!new_data->volume_writable)
1473 pa_log_debug("Not restoring volume for sink input %s, because its volume can't be changed.", name);
1474 else if (new_data->volume_is_set)
1475 pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
1476 else {
1477 pa_cvolume v;
1478
1479 pa_log_info("Restoring volume for sink input %s.", name);
1480
1481 v = e->volume;
1482 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
1483 pa_sink_input_new_data_set_volume(new_data, &v);
1484
1485 new_data->volume_is_absolute = FALSE;
1486 new_data->save_volume = TRUE;
1487 }
1488 }
1489
1490 if (u->restore_muted && e->muted_valid) {
1491
1492 if (!new_data->muted_is_set) {
1493 pa_log_info("Restoring mute state for sink input %s.", name);
1494 pa_sink_input_new_data_set_muted(new_data, e->muted);
1495 new_data->save_muted = TRUE;
1496 } else
1497 pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
1498 }
1499
1500 entry_free(e);
1501 }
1502
1503 pa_xfree(name);
1504
1505 return PA_HOOK_OK;
1506 }
1507
1508 static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
1509 char *name;
1510 struct entry *e;
1511
1512 pa_assert(c);
1513 pa_assert(new_data);
1514 pa_assert(u);
1515 pa_assert(u->restore_device);
1516
1517 if (new_data->direct_on_input)
1518 return PA_HOOK_OK;
1519
1520 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1521 return PA_HOOK_OK;
1522
1523 if (new_data->source)
1524 pa_log_debug("Not restoring device for stream %s, because already set", name);
1525 else if ((e = entry_read(u, name))) {
1526 pa_source *s = NULL;
1527
1528 if (e->device_valid)
1529 s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE);
1530
1531 if (!s && e->card_valid) {
1532 pa_card *card;
1533
1534 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1535 s = pa_idxset_first(card->sources, NULL);
1536 }
1537
1538 /* It might happen that a stream and a sink are set up at the
1539 same time, in which case we want to make sure we don't
1540 interfere with that */
1541 if (s && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) {
1542 pa_log_info("Restoring device for stream %s.", name);
1543 pa_source_output_new_data_set_source(new_data, s, TRUE);
1544 }
1545
1546 entry_free(e);
1547 }
1548
1549 pa_xfree(name);
1550
1551 return PA_HOOK_OK;
1552 }
1553
1554 static pa_hook_result_t source_output_fixate_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
1555 char *name;
1556 struct entry *e;
1557
1558 pa_assert(c);
1559 pa_assert(new_data);
1560 pa_assert(u);
1561 pa_assert(u->restore_volume || u->restore_muted);
1562
1563 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1564 return PA_HOOK_OK;
1565
1566 if ((e = entry_read(u, name))) {
1567
1568 if (u->restore_volume && e->volume_valid) {
1569 if (!new_data->volume_writable)
1570 pa_log_debug("Not restoring volume for source output %s, because its volume can't be changed.", name);
1571 else if (new_data->volume_is_set)
1572 pa_log_debug("Not restoring volume for source output %s, because already set.", name);
1573 else {
1574 pa_cvolume v;
1575
1576 pa_log_info("Restoring volume for source output %s.", name);
1577
1578 v = e->volume;
1579 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
1580 pa_source_output_new_data_set_volume(new_data, &v);
1581
1582 new_data->volume_is_absolute = FALSE;
1583 new_data->save_volume = TRUE;
1584 }
1585 }
1586
1587 if (u->restore_muted && e->muted_valid) {
1588
1589 if (!new_data->muted_is_set) {
1590 pa_log_info("Restoring mute state for source output %s.", name);
1591 pa_source_output_new_data_set_muted(new_data, e->muted);
1592 new_data->save_muted = TRUE;
1593 } else
1594 pa_log_debug("Not restoring mute state for source output %s, because already set.", name);
1595 }
1596
1597 entry_free(e);
1598 }
1599
1600 pa_xfree(name);
1601
1602 return PA_HOOK_OK;
1603 }
1604
1605 static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
1606 pa_sink_input *si;
1607 uint32_t idx;
1608
1609 pa_assert(c);
1610 pa_assert(sink);
1611 pa_assert(u);
1612 pa_assert(u->on_hotplug && u->restore_device);
1613
1614 PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
1615 char *name;
1616 struct entry *e;
1617
1618 if (si->sink == sink)
1619 continue;
1620
1621 if (si->save_sink)
1622 continue;
1623
1624 /* Skip this if it is already in the process of being moved
1625 * anyway */
1626 if (!si->sink)
1627 continue;
1628
1629 /* It might happen that a stream and a sink are set up at the
1630 same time, in which case we want to make sure we don't
1631 interfere with that */
1632 if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si)))
1633 continue;
1634
1635 if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1636 continue;
1637
1638 if ((e = entry_read(u, name))) {
1639 if (e->device_valid && pa_streq(e->device, sink->name))
1640 pa_sink_input_move_to(si, sink, TRUE);
1641
1642 entry_free(e);
1643 }
1644
1645 pa_xfree(name);
1646 }
1647
1648 return PA_HOOK_OK;
1649 }
1650
1651 static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
1652 pa_source_output *so;
1653 uint32_t idx;
1654
1655 pa_assert(c);
1656 pa_assert(source);
1657 pa_assert(u);
1658 pa_assert(u->on_hotplug && u->restore_device);
1659
1660 PA_IDXSET_FOREACH(so, c->source_outputs, idx) {
1661 char *name;
1662 struct entry *e;
1663
1664 if (so->source == source)
1665 continue;
1666
1667 if (so->save_source)
1668 continue;
1669
1670 if (so->direct_on_input)
1671 continue;
1672
1673 /* Skip this if it is already in the process of being moved anyway */
1674 if (!so->source)
1675 continue;
1676
1677 /* It might happen that a stream and a source are set up at the
1678 same time, in which case we want to make sure we don't
1679 interfere with that */
1680 if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(so)))
1681 continue;
1682
1683 if (!(name = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1684 continue;
1685
1686 if ((e = entry_read(u, name))) {
1687 if (e->device_valid && pa_streq(e->device, source->name))
1688 pa_source_output_move_to(so, source, TRUE);
1689
1690 entry_free(e);
1691 }
1692
1693 pa_xfree(name);
1694 }
1695
1696 return PA_HOOK_OK;
1697 }
1698
1699 static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
1700 pa_sink_input *si;
1701 uint32_t idx;
1702
1703 pa_assert(c);
1704 pa_assert(sink);
1705 pa_assert(u);
1706 pa_assert(u->on_rescue && u->restore_device);
1707
1708 /* There's no point in doing anything if the core is shut down anyway */
1709 if (c->state == PA_CORE_SHUTDOWN)
1710 return PA_HOOK_OK;
1711
1712 PA_IDXSET_FOREACH(si, sink->inputs, idx) {
1713 char *name;
1714 struct entry *e;
1715
1716 if (!si->sink)
1717 continue;
1718
1719 if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1720 continue;
1721
1722 if ((e = entry_read(u, name))) {
1723
1724 if (e->device_valid) {
1725 pa_sink *d;
1726
1727 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) &&
1728 d != sink &&
1729 PA_SINK_IS_LINKED(pa_sink_get_state(d)))
1730 pa_sink_input_move_to(si, d, TRUE);
1731 }
1732
1733 entry_free(e);
1734 }
1735
1736 pa_xfree(name);
1737 }
1738
1739 return PA_HOOK_OK;
1740 }
1741
1742 static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
1743 pa_source_output *so;
1744 uint32_t idx;
1745
1746 pa_assert(c);
1747 pa_assert(source);
1748 pa_assert(u);
1749 pa_assert(u->on_rescue && u->restore_device);
1750
1751 /* There's no point in doing anything if the core is shut down anyway */
1752 if (c->state == PA_CORE_SHUTDOWN)
1753 return PA_HOOK_OK;
1754
1755 PA_IDXSET_FOREACH(so, source->outputs, idx) {
1756 char *name;
1757 struct entry *e;
1758
1759 if (so->direct_on_input)
1760 continue;
1761
1762 if (!so->source)
1763 continue;
1764
1765 if (!(name = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1766 continue;
1767
1768 if ((e = entry_read(u, name))) {
1769
1770 if (e->device_valid) {
1771 pa_source *d;
1772
1773 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE)) &&
1774 d != source &&
1775 PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
1776 pa_source_output_move_to(so, d, TRUE);
1777 }
1778
1779 entry_free(e);
1780 }
1781
1782 pa_xfree(name);
1783 }
1784
1785 return PA_HOOK_OK;
1786 }
1787
1788 static int fill_db(struct userdata *u, const char *filename) {
1789 FILE *f;
1790 int n = 0;
1791 int ret = -1;
1792 char *fn = NULL;
1793
1794 pa_assert(u);
1795
1796 if (filename)
1797 f = fopen(fn = pa_xstrdup(filename), "r");
1798 else
1799 f = pa_open_config_file(DEFAULT_FALLBACK_FILE, DEFAULT_FALLBACK_FILE_USER, NULL, &fn);
1800
1801 if (!f) {
1802 if (filename)
1803 pa_log("Failed to open %s: %s", filename, pa_cstrerror(errno));
1804 else
1805 ret = 0;
1806
1807 goto finish;
1808 }
1809
1810 while (!feof(f)) {
1811 char ln[256];
1812 char *d, *v;
1813 double db;
1814
1815 if (!fgets(ln, sizeof(ln), f))
1816 break;
1817
1818 n++;
1819
1820 pa_strip_nl(ln);
1821
1822 if (!*ln || ln[0] == '#' || ln[0] == ';')
1823 continue;
1824
1825 d = ln+strcspn(ln, WHITESPACE);
1826 v = d+strspn(d, WHITESPACE);
1827
1828 if (!*v) {
1829 pa_log("[%s:%u] failed to parse line - too few words", fn, n);
1830 goto finish;
1831 }
1832
1833 *d = 0;
1834 if (pa_atod(v, &db) >= 0) {
1835 if (db <= 0.0) {
1836 pa_datum key, data;
1837 struct entry e;
1838
1839 pa_zero(e);
1840 e.version = ENTRY_VERSION;
1841 e.volume_valid = TRUE;
1842 pa_cvolume_set(&e.volume, 1, pa_sw_volume_from_dB(db));
1843 pa_channel_map_init_mono(&e.channel_map);
1844
1845 key.data = (void *) ln;
1846 key.size = strlen(ln);
1847
1848 data.data = (void *) &e;
1849 data.size = sizeof(e);
1850
1851 if (pa_database_set(u->database, &key, &data, FALSE) == 0)
1852 pa_log_debug("Setting %s to %0.2f dB.", ln, db);
1853 } else
1854 pa_log_warn("[%s:%u] Positive dB values are not allowed, not setting entry %s.", fn, n, ln);
1855 } else
1856 pa_log_warn("[%s:%u] Couldn't parse '%s' as a double, not setting entry %s.", fn, n, v, ln);
1857 }
1858
1859 trigger_save(u);
1860 ret = 0;
1861
1862 finish:
1863 if (f)
1864 fclose(f);
1865
1866 pa_xfree(fn);
1867
1868 return ret;
1869 }
1870
1871 static void entry_apply(struct userdata *u, const char *name, struct entry *e) {
1872 pa_sink_input *si;
1873 pa_source_output *so;
1874 uint32_t idx;
1875
1876 pa_assert(u);
1877 pa_assert(name);
1878 pa_assert(e);
1879
1880 PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
1881 char *n;
1882 pa_sink *s;
1883
1884 if (!(n = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1885 continue;
1886
1887 if (!pa_streq(name, n)) {
1888 pa_xfree(n);
1889 continue;
1890 }
1891 pa_xfree(n);
1892
1893 if (u->restore_volume && e->volume_valid && si->volume_writable) {
1894 pa_cvolume v;
1895
1896 v = e->volume;
1897 pa_log_info("Restoring volume for sink input %s.", name);
1898 pa_cvolume_remap(&v, &e->channel_map, &si->channel_map);
1899 pa_sink_input_set_volume(si, &v, TRUE, FALSE);
1900 }
1901
1902 if (u->restore_muted && e->muted_valid) {
1903 pa_log_info("Restoring mute state for sink input %s.", name);
1904 pa_sink_input_set_mute(si, e->muted, TRUE);
1905 }
1906
1907 if (u->restore_device) {
1908 if (!e->device_valid) {
1909 if (si->save_sink) {
1910 pa_log_info("Ensuring device is not saved for stream %s.", name);
1911 /* If the device is not valid we should make sure the
1912 save flag is cleared as the user may have specifically
1913 removed the sink element from the rule. */
1914 si->save_sink = FALSE;
1915 /* This is cheating a bit. The sink input itself has not changed
1916 but the rules governing it's routing have, so we fire this event
1917 such that other routing modules (e.g. module-device-manager)
1918 will pick up the change and reapply their routing */
1919 pa_subscription_post(si->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, si->index);
1920 }
1921 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) {
1922 pa_log_info("Restoring device for stream %s.", name);
1923 pa_sink_input_move_to(si, s, TRUE);
1924 }
1925 }
1926 }
1927
1928 PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
1929 char *n;
1930 pa_source *s;
1931
1932 if (!(n = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1933 continue;
1934
1935 if (!pa_streq(name, n)) {
1936 pa_xfree(n);
1937 continue;
1938 }
1939 pa_xfree(n);
1940
1941 if (u->restore_volume && e->volume_valid && so->volume_writable) {
1942 pa_cvolume v;
1943
1944 v = e->volume;
1945 pa_log_info("Restoring volume for source output %s.", name);
1946 pa_cvolume_remap(&v, &e->channel_map, &so->channel_map);
1947 pa_source_output_set_volume(so, &v, TRUE, FALSE);
1948 }
1949
1950 if (u->restore_muted && e->muted_valid) {
1951 pa_log_info("Restoring mute state for source output %s.", name);
1952 pa_source_output_set_mute(so, e->muted, TRUE);
1953 }
1954
1955 if (u->restore_device) {
1956 if (!e->device_valid) {
1957 if (so->save_source) {
1958 pa_log_info("Ensuring device is not saved for stream %s.", name);
1959 /* If the device is not valid we should make sure the
1960 save flag is cleared as the user may have specifically
1961 removed the source element from the rule. */
1962 so->save_source = FALSE;
1963 /* This is cheating a bit. The source output itself has not changed
1964 but the rules governing it's routing have, so we fire this event
1965 such that other routing modules (e.g. module-device-manager)
1966 will pick up the change and reapply their routing */
1967 pa_subscription_post(so->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, so->index);
1968 }
1969 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
1970 pa_log_info("Restoring device for stream %s.", name);
1971 pa_source_output_move_to(so, s, TRUE);
1972 }
1973 }
1974 }
1975 }
1976
1977 #ifdef DEBUG_VOLUME
1978 PA_GCC_UNUSED static void stream_restore_dump_database(struct userdata *u) {
1979 pa_datum key;
1980 pa_bool_t done;
1981
1982 done = !pa_database_first(u->database, &key, NULL);
1983
1984 while (!done) {
1985 pa_datum next_key;
1986 struct entry *e;
1987 char *name;
1988
1989 done = !pa_database_next(u->database, &key, &next_key, NULL);
1990
1991 name = pa_xstrndup(key.data, key.size);
1992 pa_datum_free(&key);
1993
1994 if ((e = entry_read(u, name))) {
1995 char t[256];
1996 pa_log("name=%s", name);
1997 pa_log("device=%s %s", e->device, pa_yes_no(e->device_valid));
1998 pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map));
1999 pa_log("volume=%s %s", pa_cvolume_snprint(t, sizeof(t), &e->volume), pa_yes_no(e->volume_valid));
2000 pa_log("mute=%s %s", pa_yes_no(e->muted), pa_yes_no(e->volume_valid));
2001 entry_free(e);
2002 }
2003
2004 pa_xfree(name);
2005
2006 key = next_key;
2007 }
2008 }
2009 #endif
2010
2011 #define EXT_VERSION 1
2012
2013 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
2014 struct userdata *u;
2015 uint32_t command;
2016 pa_tagstruct *reply = NULL;
2017
2018 pa_assert(p);
2019 pa_assert(m);
2020 pa_assert(c);
2021 pa_assert(t);
2022
2023 u = m->userdata;
2024
2025 if (pa_tagstruct_getu32(t, &command) < 0)
2026 goto fail;
2027
2028 reply = pa_tagstruct_new(NULL, 0);
2029 pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
2030 pa_tagstruct_putu32(reply, tag);
2031
2032 switch (command) {
2033 case SUBCOMMAND_TEST: {
2034 if (!pa_tagstruct_eof(t))
2035 goto fail;
2036
2037 pa_tagstruct_putu32(reply, EXT_VERSION);
2038 break;
2039 }
2040
2041 case SUBCOMMAND_READ: {
2042 pa_datum key;
2043 pa_bool_t done;
2044
2045 if (!pa_tagstruct_eof(t))
2046 goto fail;
2047
2048 done = !pa_database_first(u->database, &key, NULL);
2049
2050 while (!done) {
2051 pa_datum next_key;
2052 struct entry *e;
2053 char *name;
2054
2055 done = !pa_database_next(u->database, &key, &next_key, NULL);
2056
2057 name = pa_xstrndup(key.data, key.size);
2058 pa_datum_free(&key);
2059
2060 if ((e = entry_read(u, name))) {
2061 pa_cvolume r;
2062 pa_channel_map cm;
2063
2064 pa_tagstruct_puts(reply, name);
2065 pa_tagstruct_put_channel_map(reply, e->volume_valid ? &e->channel_map : pa_channel_map_init(&cm));
2066 pa_tagstruct_put_cvolume(reply, e->volume_valid ? &e->volume : pa_cvolume_init(&r));
2067 pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
2068 pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
2069
2070 entry_free(e);
2071 }
2072
2073 pa_xfree(name);
2074
2075 key = next_key;
2076 }
2077
2078 break;
2079 }
2080
2081 case SUBCOMMAND_WRITE: {
2082 uint32_t mode;
2083 pa_bool_t apply_immediately = FALSE;
2084
2085 if (pa_tagstruct_getu32(t, &mode) < 0 ||
2086 pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
2087 goto fail;
2088
2089 if (mode != PA_UPDATE_MERGE &&
2090 mode != PA_UPDATE_REPLACE &&
2091 mode != PA_UPDATE_SET)
2092 goto fail;
2093
2094 if (mode == PA_UPDATE_SET) {
2095 #ifdef HAVE_DBUS
2096 struct dbus_entry *de;
2097 void *state = NULL;
2098
2099 PA_HASHMAP_FOREACH(de, u->dbus_entries, state) {
2100 send_entry_removed_signal(de);
2101 dbus_entry_free(pa_hashmap_remove(u->dbus_entries, de->entry_name));
2102 }
2103 #endif
2104 pa_database_clear(u->database);
2105 }
2106
2107 while (!pa_tagstruct_eof(t)) {
2108 const char *name, *device;
2109 pa_bool_t muted;
2110 struct entry *entry;
2111 #ifdef HAVE_DBUS
2112 struct entry *old;
2113 #endif
2114
2115 entry = entry_new();
2116
2117 if (pa_tagstruct_gets(t, &name) < 0 ||
2118 pa_tagstruct_get_channel_map(t, &entry->channel_map) ||
2119 pa_tagstruct_get_cvolume(t, &entry->volume) < 0 ||
2120 pa_tagstruct_gets(t, &device) < 0 ||
2121 pa_tagstruct_get_boolean(t, &muted) < 0)
2122 goto fail;
2123
2124 if (!name || !*name) {
2125 entry_free(entry);
2126 goto fail;
2127 }
2128
2129 entry->volume_valid = entry->volume.channels > 0;
2130
2131 if (entry->volume_valid)
2132 if (!pa_cvolume_compatible_with_channel_map(&entry->volume, &entry->channel_map)) {
2133 entry_free(entry);
2134 goto fail;
2135 }
2136
2137 entry->muted = muted;
2138 entry->muted_valid = TRUE;
2139
2140 entry->device = pa_xstrdup(device);
2141 entry->device_valid = device && !!entry->device[0];
2142
2143 if (entry->device_valid && !pa_namereg_is_valid_name(entry->device)) {
2144 entry_free(entry);
2145 goto fail;
2146 }
2147
2148 #ifdef HAVE_DBUS
2149 old = entry_read(u, name);
2150 #endif
2151
2152 pa_log_debug("Client %s changes entry %s.",
2153 pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)),
2154 name);
2155
2156 if (entry_write(u, name, entry, mode == PA_UPDATE_REPLACE)) {
2157 #ifdef HAVE_DBUS
2158 struct dbus_entry *de;
2159
2160 if (old) {
2161 pa_assert_se((de = pa_hashmap_get(u->dbus_entries, name)));
2162
2163 if ((old->device_valid != entry->device_valid)
2164 || (entry->device_valid && !pa_streq(entry->device, old->device)))
2165 send_device_updated_signal(de, entry);
2166
2167 if ((old->volume_valid != entry->volume_valid)
2168 || (entry->volume_valid && (!pa_cvolume_equal(&entry->volume, &old->volume)
2169 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map))))
2170 send_volume_updated_signal(de, entry);
2171
2172 if (!old->muted_valid || (entry->muted != old->muted))
2173 send_mute_updated_signal(de, entry);
2174
2175 } else {
2176 de = dbus_entry_new(u, name);
2177 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
2178 send_new_entry_signal(de);
2179 }
2180 #endif
2181
2182 if (apply_immediately)
2183 entry_apply(u, name, entry);
2184 }
2185
2186 #ifdef HAVE_DBUS
2187 if (old)
2188 entry_free(old);
2189 #endif
2190 entry_free(entry);
2191 }
2192
2193 trigger_save(u);
2194
2195 break;
2196 }
2197
2198 case SUBCOMMAND_DELETE:
2199
2200 while (!pa_tagstruct_eof(t)) {
2201 const char *name;
2202 pa_datum key;
2203 #ifdef HAVE_DBUS
2204 struct dbus_entry *de;
2205 #endif
2206
2207 if (pa_tagstruct_gets(t, &name) < 0)
2208 goto fail;
2209
2210 #ifdef HAVE_DBUS
2211 if ((de = pa_hashmap_get(u->dbus_entries, name))) {
2212 send_entry_removed_signal(de);
2213 dbus_entry_free(pa_hashmap_remove(u->dbus_entries, name));
2214 }
2215 #endif
2216
2217 key.data = (char*) name;
2218 key.size = strlen(name);
2219
2220 pa_database_unset(u->database, &key);
2221 }
2222
2223 trigger_save(u);
2224
2225 break;
2226
2227 case SUBCOMMAND_SUBSCRIBE: {
2228
2229 pa_bool_t enabled;
2230
2231 if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
2232 !pa_tagstruct_eof(t))
2233 goto fail;
2234
2235 if (enabled)
2236 pa_idxset_put(u->subscribed, c, NULL);
2237 else
2238 pa_idxset_remove_by_data(u->subscribed, c, NULL);
2239
2240 break;
2241 }
2242
2243 default:
2244 goto fail;
2245 }
2246
2247 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
2248 return 0;
2249
2250 fail:
2251
2252 if (reply)
2253 pa_tagstruct_free(reply);
2254
2255 return -1;
2256 }
2257
2258 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
2259 pa_assert(p);
2260 pa_assert(c);
2261 pa_assert(u);
2262
2263 pa_idxset_remove_by_data(u->subscribed, c, NULL);
2264 return PA_HOOK_OK;
2265 }
2266
2267 static void clean_up_db(struct userdata *u) {
2268 struct clean_up_item {
2269 PA_LLIST_FIELDS(struct clean_up_item);
2270 char *entry_name;
2271 struct entry *entry;
2272 };
2273
2274 PA_LLIST_HEAD(struct clean_up_item, to_be_removed);
2275 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2276 PA_LLIST_HEAD(struct clean_up_item, to_be_converted);
2277 #endif
2278 pa_bool_t done = FALSE;
2279 pa_datum key;
2280 struct clean_up_item *item = NULL;
2281 struct clean_up_item *next = NULL;
2282
2283 pa_assert(u);
2284
2285 /* It would be convenient to remove or replace the entries in the database
2286 * in the same loop that iterates through the database, but modifying the
2287 * database is not supported while iterating through it. That's why we
2288 * collect the entries that need to be removed or replaced to these
2289 * lists. */
2290 PA_LLIST_HEAD_INIT(struct clean_up_item, to_be_removed);
2291 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2292 PA_LLIST_HEAD_INIT(struct clean_up_item, to_be_converted);
2293 #endif
2294
2295 done = !pa_database_first(u->database, &key, NULL);
2296 while (!done) {
2297 pa_datum next_key;
2298 char *entry_name = NULL;
2299 struct entry *e = NULL;
2300
2301 entry_name = pa_xstrndup(key.data, key.size);
2302
2303 /* Use entry_read() to check whether this entry is valid. */
2304 if (!(e = entry_read(u, entry_name))) {
2305 item = pa_xnew0(struct clean_up_item, 1);
2306 PA_LLIST_INIT(struct clean_up_item, item);
2307 item->entry_name = entry_name;
2308
2309 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2310 /* entry_read() failed, but what about legacy_entry_read()? */
2311 if (!(e = legacy_entry_read(u, entry_name)))
2312 /* Not a legacy entry either, let's remove this. */
2313 PA_LLIST_PREPEND(struct clean_up_item, to_be_removed, item);
2314 else {
2315 /* Yay, it's valid after all! Now let's convert the entry to the current format. */
2316 item->entry = e;
2317 PA_LLIST_PREPEND(struct clean_up_item, to_be_converted, item);
2318 }
2319 #else
2320 /* Invalid entry, let's remove this. */
2321 PA_LLIST_PREPEND(struct clean_up_item, to_be_removed, item);
2322 #endif
2323 } else {
2324 pa_xfree(entry_name);
2325 entry_free(e);
2326 }
2327
2328 done = !pa_database_next(u->database, &key, &next_key, NULL);
2329 pa_datum_free(&key);
2330 key = next_key;
2331 }
2332
2333 PA_LLIST_FOREACH_SAFE(item, next, to_be_removed) {
2334 key.data = item->entry_name;
2335 key.size = strlen(item->entry_name);
2336
2337 pa_log_debug("Removing an invalid entry: %s", item->entry_name);
2338
2339 pa_assert_se(pa_database_unset(u->database, &key) >= 0);
2340 trigger_save(u);
2341
2342 PA_LLIST_REMOVE(struct clean_up_item, to_be_removed, item);
2343 pa_xfree(item->entry_name);
2344 pa_xfree(item);
2345 }
2346
2347 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2348 PA_LLIST_FOREACH_SAFE(item, next, to_be_converted) {
2349 pa_log_debug("Upgrading a legacy entry to the current format: %s", item->entry_name);
2350
2351 pa_assert_se(entry_write(u, item->entry_name, item->entry, TRUE) >= 0);
2352 trigger_save(u);
2353
2354 PA_LLIST_REMOVE(struct clean_up_item, to_be_converted, item);
2355 pa_xfree(item->entry_name);
2356 entry_free(item->entry);
2357 pa_xfree(item);
2358 }
2359 #endif
2360 }
2361
2362 int pa__init(pa_module*m) {
2363 pa_modargs *ma = NULL;
2364 struct userdata *u;
2365 char *fname;
2366 pa_sink_input *si;
2367 pa_source_output *so;
2368 uint32_t idx;
2369 pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE, on_hotplug = TRUE, on_rescue = TRUE;
2370 #ifdef HAVE_DBUS
2371 pa_datum key;
2372 pa_bool_t done;
2373 #endif
2374
2375 pa_assert(m);
2376
2377 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
2378 pa_log("Failed to parse module arguments");
2379 goto fail;
2380 }
2381
2382 if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 ||
2383 pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
2384 pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
2385 pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 ||
2386 pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) {
2387 pa_log("restore_device=, restore_volume=, restore_muted=, on_hotplug= and on_rescue= expect boolean arguments");
2388 goto fail;
2389 }
2390
2391 if (!restore_muted && !restore_volume && !restore_device)
2392 pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring device enabled!");
2393
2394 m->userdata = u = pa_xnew0(struct userdata, 1);
2395 u->core = m->core;
2396 u->module = m;
2397 u->restore_device = restore_device;
2398 u->restore_volume = restore_volume;
2399 u->restore_muted = restore_muted;
2400 u->on_hotplug = on_hotplug;
2401 u->on_rescue = on_rescue;
2402 u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
2403
2404 u->protocol = pa_native_protocol_get(m->core);
2405 pa_native_protocol_install_ext(u->protocol, m, extension_cb);
2406
2407 u->connection_unlink_hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_CONNECTION_UNLINK], PA_HOOK_NORMAL, (pa_hook_cb_t) connection_unlink_hook_cb, u);
2408
2409 u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u);
2410
2411 if (restore_device) {
2412 /* A little bit earlier than module-intended-roles ... */
2413 u->sink_input_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_new_hook_callback, u);
2414 u->source_output_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_new_hook_callback, u);
2415 }
2416
2417 if (restore_device && on_hotplug) {
2418 /* A little bit earlier than module-intended-roles ... */
2419 u->sink_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_put_hook_callback, u);
2420 u->source_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE, (pa_hook_cb_t) source_put_hook_callback, u);
2421 }
2422
2423 if (restore_device && on_rescue) {
2424 /* A little bit earlier than module-intended-roles, module-rescue-streams, ... */
2425 u->sink_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_unlink_hook_callback, u);
2426 u->source_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) source_unlink_hook_callback, u);
2427 }
2428
2429 if (restore_volume || restore_muted) {
2430 u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
2431 u->source_output_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_fixate_hook_callback, u);
2432 }
2433
2434 if (!(fname = pa_state_path("stream-volumes", TRUE)))
2435 goto fail;
2436
2437 if (!(u->database = pa_database_open(fname, TRUE))) {
2438 pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
2439 pa_xfree(fname);
2440 goto fail;
2441 }
2442
2443 pa_log_info("Successfully opened database file '%s'.", fname);
2444 pa_xfree(fname);
2445
2446 clean_up_db(u);
2447
2448 if (fill_db(u, pa_modargs_get_value(ma, "fallback_table", NULL)) < 0)
2449 goto fail;
2450
2451 #ifdef HAVE_DBUS
2452 u->dbus_protocol = pa_dbus_protocol_get(u->core);
2453 u->dbus_entries = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
2454
2455 pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, OBJECT_PATH, &stream_restore_interface_info, u) >= 0);
2456 pa_assert_se(pa_dbus_protocol_register_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2457
2458 /* Create the initial dbus entries. */
2459 done = !pa_database_first(u->database, &key, NULL);
2460 while (!done) {
2461 pa_datum next_key;
2462 char *name;
2463 struct dbus_entry *de;
2464
2465 name = pa_xstrndup(key.data, key.size);
2466 de = dbus_entry_new(u, name);
2467 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
2468 pa_xfree(name);
2469
2470 done = !pa_database_next(u->database, &key, &next_key, NULL);
2471 pa_datum_free(&key);
2472 key = next_key;
2473 }
2474 #endif
2475
2476 PA_IDXSET_FOREACH(si, m->core->sink_inputs, idx)
2477 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, si->index, u);
2478
2479 PA_IDXSET_FOREACH(so, m->core->source_outputs, idx)
2480 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, so->index, u);
2481
2482 pa_modargs_free(ma);
2483 return 0;
2484
2485 fail:
2486 pa__done(m);
2487
2488 if (ma)
2489 pa_modargs_free(ma);
2490
2491 return -1;
2492 }
2493
2494 void pa__done(pa_module*m) {
2495 struct userdata* u;
2496
2497 pa_assert(m);
2498
2499 if (!(u = m->userdata))
2500 return;
2501
2502 #ifdef HAVE_DBUS
2503 if (u->dbus_protocol) {
2504 pa_assert(u->dbus_entries);
2505
2506 pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2507 pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, OBJECT_PATH, stream_restore_interface_info.name) >= 0);
2508
2509 pa_hashmap_free(u->dbus_entries, (pa_free_cb_t) dbus_entry_free);
2510
2511 pa_dbus_protocol_unref(u->dbus_protocol);
2512 }
2513 #endif
2514
2515 if (u->subscription)
2516 pa_subscription_free(u->subscription);
2517
2518 if (u->sink_input_new_hook_slot)
2519 pa_hook_slot_free(u->sink_input_new_hook_slot);
2520 if (u->sink_input_fixate_hook_slot)
2521 pa_hook_slot_free(u->sink_input_fixate_hook_slot);
2522 if (u->source_output_new_hook_slot)
2523 pa_hook_slot_free(u->source_output_new_hook_slot);
2524 if (u->source_output_fixate_hook_slot)
2525 pa_hook_slot_free(u->source_output_fixate_hook_slot);
2526
2527 if (u->sink_put_hook_slot)
2528 pa_hook_slot_free(u->sink_put_hook_slot);
2529 if (u->source_put_hook_slot)
2530 pa_hook_slot_free(u->source_put_hook_slot);
2531
2532 if (u->sink_unlink_hook_slot)
2533 pa_hook_slot_free(u->sink_unlink_hook_slot);
2534 if (u->source_unlink_hook_slot)
2535 pa_hook_slot_free(u->source_unlink_hook_slot);
2536
2537 if (u->connection_unlink_hook_slot)
2538 pa_hook_slot_free(u->connection_unlink_hook_slot);
2539
2540 if (u->save_time_event)
2541 u->core->mainloop->time_free(u->save_time_event);
2542
2543 if (u->database)
2544 pa_database_close(u->database);
2545
2546 if (u->protocol) {
2547 pa_native_protocol_remove_ext(u->protocol, m);
2548 pa_native_protocol_unref(u->protocol);
2549 }
2550
2551 if (u->subscribed)
2552 pa_idxset_free(u->subscribed, NULL);
2553
2554 pa_xfree(u);
2555 }