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