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