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
1033 pa_assert(u);
1034 pa_assert(name);
1035
1036 key.data = (char *) name;
1037 key.size = strlen(name);
1038
1039 pa_zero(data);
1040
1041 if (!pa_database_get(u->database, &key, &data))
1042 goto fail;
1043
1044 if (data.size != sizeof(struct legacy_entry)) {
1045 pa_log_debug("Size does not match.");
1046 goto fail;
1047 }
1048
1049 le = (struct legacy_entry *) data.data;
1050
1051 if (le->version != LEGACY_ENTRY_VERSION) {
1052 pa_log_debug("Version mismatch.");
1053 goto fail;
1054 }
1055
1056 if (!memchr(le->device, 0, sizeof(le->device))) {
1057 pa_log_warn("Device has missing NUL byte.");
1058 goto fail;
1059 }
1060
1061 if (!memchr(le->card, 0, sizeof(le->card))) {
1062 pa_log_warn("Card has missing NUL byte.");
1063 goto fail;
1064 }
1065
1066 if (le->device_valid && !pa_namereg_is_valid_name(le->device)) {
1067 pa_log_warn("Invalid device name stored in database for legacy stream");
1068 goto fail;
1069 }
1070
1071 if (le->card_valid && !pa_namereg_is_valid_name(le->card)) {
1072 pa_log_warn("Invalid card name stored in database for legacy stream");
1073 goto fail;
1074 }
1075
1076 if (le->volume_valid && !pa_channel_map_valid(&le->channel_map)) {
1077 pa_log_warn("Invalid channel map stored in database for legacy stream");
1078 goto fail;
1079 }
1080
1081 if (le->volume_valid && (!pa_cvolume_valid(&le->volume) || !pa_cvolume_compatible_with_channel_map(&le->volume, &le->channel_map))) {
1082 pa_log_warn("Invalid volume stored in database for legacy stream");
1083 goto fail;
1084 }
1085
1086 e = entry_new();
1087 e->muted_valid = le->muted_valid;
1088 e->muted = le->muted;
1089 e->volume_valid = le->volume_valid;
1090 e->channel_map = le->channel_map;
1091 e->volume = le->volume;
1092 e->device_valid = le->device_valid;
1093 e->device = pa_xstrdup(le->device);
1094 e->card_valid = le->card_valid;
1095 e->card = pa_xstrdup(le->card);
1096 return e;
1097
1098 fail:
1099 pa_datum_free(&data);
1100
1101 return NULL;
1102 }
1103 #endif
1104
entry_read(struct userdata * u,const char * name)1105 static struct entry *entry_read(struct userdata *u, const char *name) {
1106 pa_datum key, data;
1107 struct entry *e = NULL;
1108 pa_tagstruct *t = NULL;
1109 uint8_t version;
1110 const char *device, *card;
1111
1112 pa_assert(u);
1113 pa_assert(name);
1114
1115 key.data = (char*) name;
1116 key.size = strlen(name);
1117
1118 pa_zero(data);
1119
1120 if (!pa_database_get(u->database, &key, &data))
1121 goto fail;
1122
1123 t = pa_tagstruct_new_fixed(data.data, data.size);
1124 e = entry_new();
1125
1126 if (pa_tagstruct_getu8(t, &version) < 0 ||
1127 version > ENTRY_VERSION ||
1128 pa_tagstruct_get_boolean(t, &e->volume_valid) < 0 ||
1129 pa_tagstruct_get_channel_map(t, &e->channel_map) < 0 ||
1130 pa_tagstruct_get_cvolume(t, &e->volume) < 0 ||
1131 pa_tagstruct_get_boolean(t, &e->muted_valid) < 0 ||
1132 pa_tagstruct_get_boolean(t, &e->muted) < 0 ||
1133 pa_tagstruct_get_boolean(t, &e->device_valid) < 0 ||
1134 pa_tagstruct_gets(t, &device) < 0 ||
1135 pa_tagstruct_get_boolean(t, &e->card_valid) < 0 ||
1136 pa_tagstruct_gets(t, &card) < 0) {
1137
1138 goto fail;
1139 }
1140
1141 e->device = pa_xstrdup(device);
1142 e->card = pa_xstrdup(card);
1143
1144 if (!pa_tagstruct_eof(t))
1145 goto fail;
1146
1147 if (e->device_valid && (!e->device || !pa_namereg_is_valid_name(e->device))) {
1148 pa_log_warn("Invalid device name stored in database for stream %s", name);
1149 goto fail;
1150 }
1151
1152 if (e->card_valid && (!e->card || !pa_namereg_is_valid_name(e->card))) {
1153 pa_log_warn("Invalid card name stored in database for stream %s", name);
1154 goto fail;
1155 }
1156
1157 if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
1158 pa_log_warn("Invalid channel map stored in database for stream %s", name);
1159 goto fail;
1160 }
1161
1162 if (e->volume_valid && (!pa_cvolume_valid(&e->volume) || !pa_cvolume_compatible_with_channel_map(&e->volume, &e->channel_map))) {
1163 pa_log_warn("Invalid volume stored in database for stream %s", name);
1164 goto fail;
1165 }
1166
1167 pa_tagstruct_free(t);
1168 pa_datum_free(&data);
1169
1170 #ifdef STREAM_RESTORE_CLEAR_OLD_DEVICES
1171 if (version < ENTRY_VERSION && e->device_valid) {
1172 /* Prior to PulseAudio 14.0, GNOME's sound settings overwrote the
1173 * routing for all entries in the stream-restore database when
1174 * selecting a device. PulseAudio 14.0 prevents that from happening,
1175 * but the old overwritten settings can still be in the database after
1176 * updating to PulseAudio 14.0, and they can cause problems, as
1177 * documented here:
1178 * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832
1179 *
1180 * We can't distinguish between devices set by GNOME's sound settings
1181 * and devices set by the user, so we discard all old device settings,
1182 * even though that is going to cause PulseAudio to forget routing
1183 * settings for many users. This is less bad than keeping the incorrect
1184 * routing settings in the database, because it's difficult for users
1185 * to figure out how to fix the situation when e.g. speaker test tones
1186 * go to the internal speakers no matter what device is selected as the
1187 * default, whereas old manual configuration can be restored restored
1188 * by doing the manual configuration again. Also, it's probably more
1189 * common to have at some point changed the default device in GNOME's
1190 * sound settings than it is to have any manual per-stream routing
1191 * settings. */
1192 pa_log_warn("Device set, but it might be incorrect. Clearing the device. If this messes up your manual stream "
1193 "routing configuration, sorry about that. This is a workaround for this bug: "
1194 "https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832");
1195 pa_log_warn("%s: device: %s -> (unset)", name, e->device);
1196 pa_xfree(e->device);
1197 e->device = NULL;
1198 e->device_valid = false;
1199 if (e->card_valid) {
1200 pa_log_warn("%s: card: %s -> (unset)", name, e->card);
1201 pa_xfree(e->card);
1202 e->card = NULL;
1203 e->card_valid = false;
1204 }
1205 entry_write(u, name, e, true);
1206 trigger_save(u);
1207 }
1208 #endif
1209
1210 return e;
1211
1212 fail:
1213 if (e)
1214 entry_free(e);
1215 if (t)
1216 pa_tagstruct_free(t);
1217
1218 pa_datum_free(&data);
1219 return NULL;
1220 }
1221
entry_copy(const struct entry * e)1222 static struct entry* entry_copy(const struct entry *e) {
1223 struct entry* r;
1224
1225 pa_assert(e);
1226 r = entry_new();
1227 *r = *e;
1228 r->device = pa_xstrdup(e->device);
1229 r->card = pa_xstrdup(e->card);
1230 return r;
1231 }
1232
trigger_save(struct userdata * u)1233 static void trigger_save(struct userdata *u) {
1234 pa_native_connection *c;
1235 uint32_t idx;
1236
1237 PA_IDXSET_FOREACH(c, u->subscribed, idx) {
1238 pa_tagstruct *t;
1239
1240 t = pa_tagstruct_new();
1241 pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
1242 pa_tagstruct_putu32(t, 0);
1243 pa_tagstruct_putu32(t, u->module->index);
1244 pa_tagstruct_puts(t, u->module->name);
1245 pa_tagstruct_putu32(t, SUBCOMMAND_EVENT);
1246
1247 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t);
1248 }
1249
1250 if (u->save_time_event)
1251 return;
1252
1253 u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
1254 }
1255
entries_equal(const struct entry * a,const struct entry * b)1256 static bool entries_equal(const struct entry *a, const struct entry *b) {
1257 pa_cvolume t;
1258
1259 pa_assert(a);
1260 pa_assert(b);
1261
1262 if (a->device_valid != b->device_valid ||
1263 (a->device_valid && !pa_streq(a->device, b->device)))
1264 return false;
1265
1266 if (a->card_valid != b->card_valid ||
1267 (a->card_valid && !pa_streq(a->card, b->card)))
1268 return false;
1269
1270 if (a->muted_valid != b->muted_valid ||
1271 (a->muted_valid && (a->muted != b->muted)))
1272 return false;
1273
1274 t = b->volume;
1275 if (a->volume_valid != b->volume_valid ||
1276 (a->volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->volume)))
1277 return false;
1278
1279 return true;
1280 }
1281
subscribe_callback(pa_core * c,pa_subscription_event_type_t t,uint32_t idx,void * userdata)1282 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
1283 struct userdata *u = userdata;
1284 struct entry *entry, *old = NULL;
1285 char *name = NULL;
1286
1287 /* These are only used when D-Bus is enabled, but in order to reduce ifdef
1288 * clutter these are defined here unconditionally. */
1289 bool created_new_entry = true;
1290 bool device_updated = false;
1291 bool volume_updated = false;
1292 bool mute_updated = false;
1293
1294 #ifdef HAVE_DBUS
1295 struct dbus_entry *de = NULL;
1296 #endif
1297
1298 pa_assert(c);
1299 pa_assert(u);
1300
1301 if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW) &&
1302 t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) &&
1303 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW) &&
1304 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
1305 return;
1306
1307 if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
1308 pa_sink_input *sink_input;
1309
1310 if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx)))
1311 return;
1312
1313 /* Ignore this sink input if it is connecting a filter sink to
1314 * the master */
1315 if (sink_input->origin_sink)
1316 return;
1317
1318 if (!(name = pa_proplist_get_stream_group(sink_input->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1319 return;
1320
1321 if ((old = entry_read(u, name))) {
1322 entry = entry_copy(old);
1323 created_new_entry = false;
1324 } else
1325 entry = entry_new();
1326
1327 if (sink_input->save_volume && pa_sink_input_is_volume_readable(sink_input)) {
1328 pa_assert(sink_input->volume_writable);
1329
1330 entry->channel_map = sink_input->channel_map;
1331 pa_sink_input_get_volume(sink_input, &entry->volume, false);
1332 entry->volume_valid = true;
1333
1334 volume_updated = !created_new_entry
1335 && (!old->volume_valid
1336 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map)
1337 || !pa_cvolume_equal(&entry->volume, &old->volume));
1338 }
1339
1340 if (sink_input->save_muted) {
1341 entry->muted = sink_input->muted;
1342 entry->muted_valid = true;
1343
1344 mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
1345 }
1346
1347 if (sink_input->preferred_sink != NULL || !created_new_entry) {
1348 pa_sink *s = NULL;
1349
1350 pa_xfree(entry->device);
1351 entry->device = pa_xstrdup(sink_input->preferred_sink);
1352 entry->device_valid = true;
1353 if (!entry->device)
1354 entry->device_valid = false;
1355
1356 device_updated = !created_new_entry && !pa_safe_streq(entry->device, old->device);
1357 pa_xfree(entry->card);
1358 entry->card = NULL;
1359 entry->card_valid = false;
1360 if (entry->device_valid && (s = pa_namereg_get(c, entry->device, PA_NAMEREG_SINK)) && s->card) {
1361 entry->card = pa_xstrdup(s->card->name);
1362 entry->card_valid = true;
1363 }
1364 }
1365 } else {
1366 pa_source_output *source_output;
1367
1368 pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT);
1369
1370 if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx)))
1371 return;
1372
1373 /* Ignore this source output if it is connecting a filter source to
1374 * the master */
1375 if (source_output->destination_source)
1376 return;
1377
1378 if (!(name = pa_proplist_get_stream_group(source_output->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1379 return;
1380
1381 if ((old = entry_read(u, name))) {
1382 entry = entry_copy(old);
1383 created_new_entry = false;
1384 } else
1385 entry = entry_new();
1386
1387 if (source_output->save_volume && pa_source_output_is_volume_readable(source_output)) {
1388 pa_assert(source_output->volume_writable);
1389
1390 entry->channel_map = source_output->channel_map;
1391 pa_source_output_get_volume(source_output, &entry->volume, false);
1392 entry->volume_valid = true;
1393
1394 volume_updated = !created_new_entry
1395 && (!old->volume_valid
1396 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map)
1397 || !pa_cvolume_equal(&entry->volume, &old->volume));
1398 }
1399
1400 if (source_output->save_muted) {
1401 entry->muted = source_output->muted;
1402 entry->muted_valid = true;
1403
1404 mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
1405 }
1406
1407 if (source_output->preferred_source != NULL || !created_new_entry) {
1408 pa_source *s = NULL;
1409
1410 pa_xfree(entry->device);
1411 entry->device = pa_xstrdup(source_output->preferred_source);
1412 entry->device_valid = true;
1413
1414 if (!entry->device)
1415 entry->device_valid = false;
1416
1417 device_updated = !created_new_entry && !pa_safe_streq(entry->device, old->device);
1418 pa_xfree(entry->card);
1419 entry->card = NULL;
1420 entry->card_valid = false;
1421 if (entry->device_valid && (s = pa_namereg_get(c, entry->device, PA_NAMEREG_SOURCE)) && s->card) {
1422 entry->card = pa_xstrdup(s->card->name);
1423 entry->card_valid = true;
1424 }
1425 }
1426 }
1427
1428 pa_assert(entry);
1429
1430 if (old) {
1431
1432 if (entries_equal(old, entry)) {
1433 entry_free(old);
1434 entry_free(entry);
1435 pa_xfree(name);
1436 return;
1437 }
1438
1439 entry_free(old);
1440 }
1441
1442 pa_log_info("Storing volume/mute/device for stream %s.", name);
1443
1444 if (entry_write(u, name, entry, true)) {
1445 trigger_save(u);
1446 } else {
1447 pa_log_error("Could not store volume/mute/device for stream %s.", name);
1448 }
1449
1450 #ifdef HAVE_DBUS
1451 if (!(de = pa_hashmap_get(u->dbus_entries, name))) {
1452 de = dbus_entry_new(u, name);
1453 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
1454 send_new_entry_signal(de);
1455 } else {
1456 if (device_updated)
1457 send_device_updated_signal(de, entry);
1458 if (volume_updated)
1459 send_volume_updated_signal(de, entry);
1460 if (mute_updated)
1461 send_mute_updated_signal(de, entry);
1462 }
1463 #else
1464 /* Silence compiler warnings */
1465 (void) device_updated;
1466 (void) volume_updated;
1467 (void) mute_updated;
1468 #endif
1469
1470 entry_free(entry);
1471 pa_xfree(name);
1472 }
1473
sink_input_new_hook_callback(pa_core * c,pa_sink_input_new_data * new_data,struct userdata * u)1474 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1475 char *name;
1476 struct entry *e;
1477
1478 pa_assert(c);
1479 pa_assert(new_data);
1480 pa_assert(u);
1481 pa_assert(u->restore_device);
1482
1483 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1484 return PA_HOOK_OK;
1485
1486 if (new_data->sink)
1487 pa_log_debug("Not restoring device for stream %s, because already set to '%s'.", name, new_data->sink->name);
1488 else if (new_data->origin_sink)
1489 pa_log_debug("Not restoring device for stream %s, because it connects a filter to the master sink.", name);
1490 else if ((e = entry_read(u, name))) {
1491 pa_sink *s = NULL;
1492
1493 if (e->device_valid) {
1494 s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK);
1495 new_data->preferred_sink = pa_xstrdup(e->device);
1496 }
1497
1498 if (!s && e->card_valid) {
1499 pa_card *card;
1500
1501 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1502 s = pa_idxset_first(card->sinks, NULL);
1503 }
1504
1505 /* It might happen that a stream and a sink are set up at the
1506 same time, in which case we want to make sure we don't
1507 interfere with that */
1508 if (s && PA_SINK_IS_LINKED(s->state))
1509 if (!s->active_port || s->active_port->available != PA_AVAILABLE_NO) {
1510 if (pa_sink_input_new_data_set_sink(new_data, s, true, false))
1511 pa_log_info("Restoring device for stream %s.", name);
1512 }
1513
1514 entry_free(e);
1515 }
1516
1517 pa_xfree(name);
1518
1519 return PA_HOOK_OK;
1520 }
1521
sink_input_fixate_hook_callback(pa_core * c,pa_sink_input_new_data * new_data,struct userdata * u)1522 static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1523 char *name;
1524 struct entry *e;
1525
1526 pa_assert(c);
1527 pa_assert(new_data);
1528 pa_assert(u);
1529 pa_assert(u->restore_volume || u->restore_muted);
1530
1531 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1532 return PA_HOOK_OK;
1533
1534 if (new_data->origin_sink) {
1535 pa_log_debug("Not restoring volume for sink input %s, because it connects a filter to the master sink.", name);
1536 return PA_HOOK_OK;
1537 }
1538
1539 if ((e = entry_read(u, name))) {
1540
1541 if (u->restore_volume && e->volume_valid) {
1542 if (!new_data->volume_writable)
1543 pa_log_debug("Not restoring volume for sink input %s, because its volume can't be changed.", name);
1544 else if (new_data->volume_is_set)
1545 pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
1546 else {
1547 pa_cvolume v;
1548
1549 pa_log_info("Restoring volume for sink input %s.", name);
1550
1551 v = e->volume;
1552 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
1553 pa_sink_input_new_data_set_volume(new_data, &v);
1554
1555 new_data->volume_is_absolute = false;
1556 new_data->save_volume = true;
1557 }
1558 }
1559
1560 if (u->restore_muted && e->muted_valid) {
1561
1562 if (!new_data->muted_is_set) {
1563 pa_log_info("Restoring mute state for sink input %s.", name);
1564 pa_sink_input_new_data_set_muted(new_data, e->muted);
1565 new_data->save_muted = true;
1566 } else
1567 pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
1568 }
1569
1570 entry_free(e);
1571 }
1572
1573 pa_xfree(name);
1574
1575 return PA_HOOK_OK;
1576 }
1577
source_output_new_hook_callback(pa_core * c,pa_source_output_new_data * new_data,struct userdata * u)1578 static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
1579 char *name;
1580 struct entry *e;
1581
1582 pa_assert(c);
1583 pa_assert(new_data);
1584 pa_assert(u);
1585 pa_assert(u->restore_device);
1586
1587 if (new_data->direct_on_input)
1588 return PA_HOOK_OK;
1589
1590 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1591 return PA_HOOK_OK;
1592
1593 if (new_data->source)
1594 pa_log_debug("Not restoring device for stream %s, because already set", name);
1595 else if (new_data->destination_source)
1596 pa_log_debug("Not restoring device for stream %s, because it connects a filter to the master source.", name);
1597 else if ((e = entry_read(u, name))) {
1598 pa_source *s = NULL;
1599
1600 if (e->device_valid) {
1601 s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE);
1602 new_data->preferred_source = pa_xstrdup(e->device);
1603 }
1604
1605 if (!s && e->card_valid) {
1606 pa_card *card;
1607
1608 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1609 s = pa_idxset_first(card->sources, NULL);
1610 }
1611
1612 /* It might happen that a stream and a sink are set up at the
1613 same time, in which case we want to make sure we don't
1614 interfere with that */
1615 if (s && PA_SOURCE_IS_LINKED(s->state)) {
1616 if (!s->active_port || s->active_port->available != PA_AVAILABLE_NO) {
1617 pa_log_info("Restoring device for stream %s.", name);
1618 pa_source_output_new_data_set_source(new_data, s, true, false);
1619 }
1620 }
1621
1622 entry_free(e);
1623 }
1624
1625 pa_xfree(name);
1626
1627 return PA_HOOK_OK;
1628 }
1629
source_output_fixate_hook_callback(pa_core * c,pa_source_output_new_data * new_data,struct userdata * u)1630 static pa_hook_result_t source_output_fixate_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
1631 char *name;
1632 struct entry *e;
1633
1634 pa_assert(c);
1635 pa_assert(new_data);
1636 pa_assert(u);
1637 pa_assert(u->restore_volume || u->restore_muted);
1638
1639 if (!(name = pa_proplist_get_stream_group(new_data->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1640 return PA_HOOK_OK;
1641
1642 if (new_data->destination_source) {
1643 pa_log_debug("Not restoring volume for source output %s, because it connects a filter to the master source.", name);
1644 return PA_HOOK_OK;
1645 }
1646
1647 if ((e = entry_read(u, name))) {
1648
1649 if (u->restore_volume && e->volume_valid) {
1650 if (!new_data->volume_writable)
1651 pa_log_debug("Not restoring volume for source output %s, because its volume can't be changed.", name);
1652 else if (new_data->volume_is_set)
1653 pa_log_debug("Not restoring volume for source output %s, because already set.", name);
1654 else {
1655 pa_cvolume v;
1656
1657 pa_log_info("Restoring volume for source output %s.", name);
1658
1659 v = e->volume;
1660 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
1661 pa_source_output_new_data_set_volume(new_data, &v);
1662
1663 new_data->volume_is_absolute = false;
1664 new_data->save_volume = true;
1665 }
1666 }
1667
1668 if (u->restore_muted && e->muted_valid) {
1669
1670 if (!new_data->muted_is_set) {
1671 pa_log_info("Restoring mute state for source output %s.", name);
1672 pa_source_output_new_data_set_muted(new_data, e->muted);
1673 new_data->save_muted = true;
1674 } else
1675 pa_log_debug("Not restoring mute state for source output %s, because already set.", name);
1676 }
1677
1678 entry_free(e);
1679 }
1680
1681 pa_xfree(name);
1682
1683 return PA_HOOK_OK;
1684 }
1685
fill_db(struct userdata * u,const char * filename)1686 static int fill_db(struct userdata *u, const char *filename) {
1687 FILE *f;
1688 int n = 0;
1689 int ret = -1;
1690 char *fn = NULL;
1691
1692 pa_assert(u);
1693
1694 if (filename)
1695 f = fopen(fn = pa_xstrdup(filename), "r");
1696 else
1697 f = pa_open_config_file(DEFAULT_FALLBACK_FILE, DEFAULT_FALLBACK_FILE_USER, NULL, &fn);
1698
1699 if (!f) {
1700 if (filename)
1701 pa_log("Failed to open %s: %s", filename, pa_cstrerror(errno));
1702 else
1703 ret = 0;
1704
1705 goto finish;
1706 }
1707
1708 while (!feof(f)) {
1709 char ln[256];
1710 char *d, *v;
1711 double db;
1712
1713 if (!fgets(ln, sizeof(ln), f))
1714 break;
1715
1716 n++;
1717
1718 pa_strip_nl(ln);
1719
1720 if (!*ln || ln[0] == '#' || ln[0] == ';')
1721 continue;
1722
1723 d = ln+strcspn(ln, WHITESPACE);
1724 v = d+strspn(d, WHITESPACE);
1725
1726 if (!*v) {
1727 pa_log("[%s:%u] failed to parse line - too few words", fn, n);
1728 goto finish;
1729 }
1730
1731 *d = 0;
1732 if (pa_atod(v, &db) >= 0) {
1733 if (db <= 0.0) {
1734 struct entry e;
1735
1736 pa_zero(e);
1737 e.volume_valid = true;
1738 pa_cvolume_set(&e.volume, 1, pa_sw_volume_from_dB(db));
1739 pa_channel_map_init_mono(&e.channel_map);
1740
1741 if (entry_write(u, ln, &e, false))
1742 pa_log_debug("Setting %s to %0.2f dB.", ln, db);
1743 } else
1744 pa_log_warn("[%s:%u] Positive dB values are not allowed, not setting entry %s.", fn, n, ln);
1745 } else
1746 pa_log_warn("[%s:%u] Couldn't parse '%s' as a double, not setting entry %s.", fn, n, v, ln);
1747 }
1748
1749 trigger_save(u);
1750 ret = 0;
1751
1752 finish:
1753 if (f)
1754 fclose(f);
1755
1756 pa_xfree(fn);
1757
1758 return ret;
1759 }
1760
entry_apply(struct userdata * u,const char * name,struct entry * e)1761 static void entry_apply(struct userdata *u, const char *name, struct entry *e) {
1762 pa_sink_input *si;
1763 pa_source_output *so;
1764 uint32_t idx;
1765
1766 pa_assert(u);
1767 pa_assert(name);
1768 pa_assert(e);
1769
1770 PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
1771 char *n;
1772 pa_sink *s;
1773
1774 if (!(n = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
1775 continue;
1776
1777 if (!pa_streq(name, n)) {
1778 pa_xfree(n);
1779 continue;
1780 }
1781 pa_xfree(n);
1782
1783 if (u->restore_volume && e->volume_valid && si->volume_writable) {
1784 pa_cvolume v;
1785
1786 v = e->volume;
1787 pa_log_info("Restoring volume for sink input %s.", name);
1788 pa_cvolume_remap(&v, &e->channel_map, &si->channel_map);
1789 pa_sink_input_set_volume(si, &v, true, false);
1790 }
1791
1792 if (u->restore_muted && e->muted_valid) {
1793 pa_log_info("Restoring mute state for sink input %s.", name);
1794 pa_sink_input_set_mute(si, e->muted, true);
1795 }
1796
1797 if (u->restore_device) {
1798 if (!e->device_valid) {
1799 if (si->preferred_sink != NULL) {
1800 pa_log_info("Ensuring device is not saved for stream %s.", name);
1801 /* If the device is not valid we should make sure the
1802 preferred_sink is cleared as the user may have specifically
1803 removed the sink element from the rule. */
1804 pa_sink_input_set_preferred_sink(si, NULL);
1805 }
1806 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) {
1807 pa_log_info("Restoring device for stream %s.", name);
1808 pa_sink_input_set_preferred_sink(si, s);
1809 }
1810 }
1811 }
1812
1813 PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
1814 char *n;
1815 pa_source *s;
1816
1817 if (!(n = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
1818 continue;
1819
1820 if (!pa_streq(name, n)) {
1821 pa_xfree(n);
1822 continue;
1823 }
1824 pa_xfree(n);
1825
1826 if (u->restore_volume && e->volume_valid && so->volume_writable) {
1827 pa_cvolume v;
1828
1829 v = e->volume;
1830 pa_log_info("Restoring volume for source output %s.", name);
1831 pa_cvolume_remap(&v, &e->channel_map, &so->channel_map);
1832 pa_source_output_set_volume(so, &v, true, false);
1833 }
1834
1835 if (u->restore_muted && e->muted_valid) {
1836 pa_log_info("Restoring mute state for source output %s.", name);
1837 pa_source_output_set_mute(so, e->muted, true);
1838 }
1839
1840 if (u->restore_device) {
1841 if (!e->device_valid) {
1842 if (so->preferred_source != NULL) {
1843 pa_log_info("Ensuring device is not saved for stream %s.", name);
1844 /* If the device is not valid we should make sure the
1845 preferred_source is cleared as the user may have specifically
1846 removed the source element from the rule. */
1847 pa_source_output_set_preferred_source(so, NULL);
1848 }
1849 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
1850 pa_log_info("Restoring device for stream %s.", name);
1851 pa_source_output_set_preferred_source(so, s);
1852 }
1853 }
1854 }
1855 }
1856
1857 #ifdef DEBUG_VOLUME
stream_restore_dump_database(struct userdata * u)1858 PA_GCC_UNUSED static void stream_restore_dump_database(struct userdata *u) {
1859 pa_datum key;
1860 bool done;
1861
1862 done = !pa_database_first(u->database, &key, NULL);
1863
1864 while (!done) {
1865 pa_datum next_key;
1866 struct entry *e;
1867 char *name;
1868
1869 done = !pa_database_next(u->database, &key, &next_key, NULL);
1870
1871 name = pa_xstrndup(key.data, key.size);
1872 pa_datum_free(&key);
1873
1874 if ((e = entry_read(u, name))) {
1875 char t[256];
1876 pa_log("name=%s", name);
1877 pa_log("device=%s %s", e->device, pa_yes_no(e->device_valid));
1878 pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map));
1879 pa_log("volume=%s %s",
1880 pa_cvolume_snprint_verbose(t, sizeof(t), &e->volume, &e->channel_map, true),
1881 pa_yes_no(e->volume_valid));
1882 pa_log("mute=%s %s", pa_yes_no(e->muted), pa_yes_no(e->volume_valid));
1883 entry_free(e);
1884 }
1885
1886 pa_xfree(name);
1887
1888 key = next_key;
1889 }
1890 }
1891 #endif
1892
1893 #define EXT_VERSION 1
1894
extension_cb(pa_native_protocol * p,pa_module * m,pa_native_connection * c,uint32_t tag,pa_tagstruct * t)1895 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
1896 struct userdata *u;
1897 uint32_t command;
1898 pa_tagstruct *reply = NULL;
1899
1900 pa_assert(p);
1901 pa_assert(m);
1902 pa_assert(c);
1903 pa_assert(t);
1904
1905 u = m->userdata;
1906
1907 if (pa_tagstruct_getu32(t, &command) < 0)
1908 goto fail;
1909
1910 reply = pa_tagstruct_new();
1911 pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
1912 pa_tagstruct_putu32(reply, tag);
1913
1914 switch (command) {
1915 case SUBCOMMAND_TEST: {
1916 if (!pa_tagstruct_eof(t))
1917 goto fail;
1918
1919 pa_tagstruct_putu32(reply, EXT_VERSION);
1920 break;
1921 }
1922
1923 case SUBCOMMAND_READ: {
1924 pa_datum key;
1925 bool done;
1926
1927 if (!pa_tagstruct_eof(t))
1928 goto fail;
1929
1930 done = !pa_database_first(u->database, &key, NULL);
1931
1932 while (!done) {
1933 pa_datum next_key;
1934 struct entry *e;
1935 char *name;
1936
1937 done = !pa_database_next(u->database, &key, &next_key, NULL);
1938
1939 name = pa_xstrndup(key.data, key.size);
1940 pa_datum_free(&key);
1941
1942 if ((e = entry_read(u, name))) {
1943 pa_cvolume r;
1944 pa_channel_map cm;
1945
1946 pa_tagstruct_puts(reply, name);
1947 pa_tagstruct_put_channel_map(reply, e->volume_valid ? &e->channel_map : pa_channel_map_init(&cm));
1948 pa_tagstruct_put_cvolume(reply, e->volume_valid ? &e->volume : pa_cvolume_init(&r));
1949 pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
1950 pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : false);
1951
1952 entry_free(e);
1953 }
1954
1955 pa_xfree(name);
1956
1957 key = next_key;
1958 }
1959
1960 break;
1961 }
1962
1963 case SUBCOMMAND_WRITE: {
1964 uint32_t mode;
1965 bool apply_immediately = false;
1966
1967 if (pa_tagstruct_getu32(t, &mode) < 0 ||
1968 pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
1969 goto fail;
1970
1971 if (mode != PA_UPDATE_MERGE &&
1972 mode != PA_UPDATE_REPLACE &&
1973 mode != PA_UPDATE_SET)
1974 goto fail;
1975
1976 if (mode == PA_UPDATE_SET) {
1977 #ifdef HAVE_DBUS
1978 struct dbus_entry *de;
1979 void *state = NULL;
1980
1981 PA_HASHMAP_FOREACH(de, u->dbus_entries, state) {
1982 send_entry_removed_signal(de);
1983 pa_hashmap_remove_and_free(u->dbus_entries, de->entry_name);
1984 }
1985 #endif
1986 pa_database_clear(u->database);
1987 }
1988
1989 while (!pa_tagstruct_eof(t)) {
1990 const char *name, *device, *client_name;
1991 bool muted;
1992 struct entry *entry;
1993 #ifdef HAVE_DBUS
1994 struct entry *old;
1995 #endif
1996
1997 entry = entry_new();
1998
1999 if (pa_tagstruct_gets(t, &name) < 0 ||
2000 pa_tagstruct_get_channel_map(t, &entry->channel_map) ||
2001 pa_tagstruct_get_cvolume(t, &entry->volume) < 0 ||
2002 pa_tagstruct_gets(t, &device) < 0 ||
2003 pa_tagstruct_get_boolean(t, &muted) < 0) {
2004 entry_free(entry);
2005 goto fail;
2006 }
2007
2008 if (!name || !*name) {
2009 entry_free(entry);
2010 goto fail;
2011 }
2012
2013 entry->volume_valid = entry->volume.channels > 0;
2014
2015 if (entry->volume_valid)
2016 if (!pa_cvolume_compatible_with_channel_map(&entry->volume, &entry->channel_map)) {
2017 entry_free(entry);
2018 goto fail;
2019 }
2020
2021 entry->muted = muted;
2022 entry->muted_valid = true;
2023
2024 entry->device = pa_xstrdup(device);
2025 entry->device_valid = device && !!entry->device[0];
2026
2027 if (entry->device_valid && !pa_namereg_is_valid_name(entry->device)) {
2028 entry_free(entry);
2029 goto fail;
2030 }
2031 /* When users select an output device from gnome-control-center, the gnome-control-center will change all entries
2032 * in the database to bind the sink of this output device, this is not correct since at this moment, the sink is
2033 * default_sink and we shouldn't bind a stream to default_sink via preferred_sink or database. This also applies
2034 * to source, default_source and preferred_source.
2035 * After gnome-control-center fix the issue, let us remove this code */
2036 client_name = pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
2037 if (pa_safe_streq(client_name, "gnome-control-center")) {
2038 if (entry->device_valid && ((m->core->default_sink && pa_safe_streq(device, m->core->default_sink->name)) ||
2039 (m->core->default_source && pa_safe_streq(device, m->core->default_source->name)))) {
2040 entry_free(entry);
2041 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
2042 return 0;
2043 }
2044 }
2045 #ifdef HAVE_DBUS
2046 old = entry_read(u, name);
2047 #endif
2048
2049 pa_log_debug("Client %s changes entry %s.",
2050 pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)),
2051 name);
2052
2053 if (entry_write(u, name, entry, mode == PA_UPDATE_REPLACE)) {
2054 #ifdef HAVE_DBUS
2055 struct dbus_entry *de;
2056
2057 if (old) {
2058 pa_assert_se((de = pa_hashmap_get(u->dbus_entries, name)));
2059
2060 if ((old->device_valid != entry->device_valid)
2061 || (entry->device_valid && !pa_streq(entry->device, old->device)))
2062 send_device_updated_signal(de, entry);
2063
2064 if ((old->volume_valid != entry->volume_valid)
2065 || (entry->volume_valid && (!pa_cvolume_equal(&entry->volume, &old->volume)
2066 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map))))
2067 send_volume_updated_signal(de, entry);
2068
2069 if (!old->muted_valid || (entry->muted != old->muted))
2070 send_mute_updated_signal(de, entry);
2071
2072 } else {
2073 de = dbus_entry_new(u, name);
2074 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
2075 send_new_entry_signal(de);
2076 }
2077 #endif
2078
2079 if (apply_immediately)
2080 entry_apply(u, name, entry);
2081 }
2082
2083 #ifdef HAVE_DBUS
2084 if (old)
2085 entry_free(old);
2086 #endif
2087 entry_free(entry);
2088 }
2089
2090 trigger_save(u);
2091
2092 break;
2093 }
2094
2095 case SUBCOMMAND_DELETE:
2096
2097 while (!pa_tagstruct_eof(t)) {
2098 const char *name;
2099 pa_datum key;
2100 #ifdef HAVE_DBUS
2101 struct dbus_entry *de;
2102 #endif
2103
2104 if (pa_tagstruct_gets(t, &name) < 0)
2105 goto fail;
2106
2107 #ifdef HAVE_DBUS
2108 if ((de = pa_hashmap_get(u->dbus_entries, name))) {
2109 send_entry_removed_signal(de);
2110 pa_hashmap_remove_and_free(u->dbus_entries, name);
2111 }
2112 #endif
2113
2114 key.data = (char*) name;
2115 key.size = strlen(name);
2116
2117 pa_database_unset(u->database, &key);
2118 }
2119
2120 trigger_save(u);
2121
2122 break;
2123
2124 case SUBCOMMAND_SUBSCRIBE: {
2125
2126 bool enabled;
2127
2128 if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
2129 !pa_tagstruct_eof(t))
2130 goto fail;
2131
2132 if (enabled)
2133 pa_idxset_put(u->subscribed, c, NULL);
2134 else
2135 pa_idxset_remove_by_data(u->subscribed, c, NULL);
2136
2137 break;
2138 }
2139
2140 default:
2141 goto fail;
2142 }
2143
2144 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
2145 return 0;
2146
2147 fail:
2148
2149 if (reply)
2150 pa_tagstruct_free(reply);
2151
2152 return -1;
2153 }
2154
connection_unlink_hook_cb(pa_native_protocol * p,pa_native_connection * c,struct userdata * u)2155 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
2156 pa_assert(p);
2157 pa_assert(c);
2158 pa_assert(u);
2159
2160 pa_idxset_remove_by_data(u->subscribed, c, NULL);
2161 return PA_HOOK_OK;
2162 }
2163
clean_up_db(struct userdata * u)2164 static void clean_up_db(struct userdata *u) {
2165 struct clean_up_item {
2166 PA_LLIST_FIELDS(struct clean_up_item);
2167 char *entry_name;
2168 struct entry *entry;
2169 };
2170
2171 PA_LLIST_HEAD(struct clean_up_item, to_be_removed);
2172 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2173 PA_LLIST_HEAD(struct clean_up_item, to_be_converted);
2174 #endif
2175 bool done = false;
2176 pa_datum key;
2177 struct clean_up_item *item = NULL;
2178 struct clean_up_item *next = NULL;
2179
2180 pa_assert(u);
2181
2182 /* It would be convenient to remove or replace the entries in the database
2183 * in the same loop that iterates through the database, but modifying the
2184 * database is not supported while iterating through it. That's why we
2185 * collect the entries that need to be removed or replaced to these
2186 * lists. */
2187 PA_LLIST_HEAD_INIT(struct clean_up_item, to_be_removed);
2188 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2189 PA_LLIST_HEAD_INIT(struct clean_up_item, to_be_converted);
2190 #endif
2191
2192 done = !pa_database_first(u->database, &key, NULL);
2193 while (!done) {
2194 pa_datum next_key;
2195 char *entry_name = NULL;
2196 struct entry *e = NULL;
2197
2198 entry_name = pa_xstrndup(key.data, key.size);
2199
2200 /* Use entry_read() to check whether this entry is valid. */
2201 if (!(e = entry_read(u, entry_name))) {
2202 item = pa_xnew0(struct clean_up_item, 1);
2203 PA_LLIST_INIT(struct clean_up_item, item);
2204 item->entry_name = entry_name;
2205
2206 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2207 /* entry_read() failed, but what about legacy_entry_read()? */
2208 if (!(e = legacy_entry_read(u, entry_name)))
2209 /* Not a legacy entry either, let's remove this. */
2210 PA_LLIST_PREPEND(struct clean_up_item, to_be_removed, item);
2211 else {
2212 /* Yay, it's valid after all! Now let's convert the entry to the current format. */
2213 item->entry = e;
2214 PA_LLIST_PREPEND(struct clean_up_item, to_be_converted, item);
2215 }
2216 #else
2217 /* Invalid entry, let's remove this. */
2218 PA_LLIST_PREPEND(struct clean_up_item, to_be_removed, item);
2219 #endif
2220 } else {
2221 pa_xfree(entry_name);
2222 entry_free(e);
2223 }
2224
2225 done = !pa_database_next(u->database, &key, &next_key, NULL);
2226 pa_datum_free(&key);
2227 key = next_key;
2228 }
2229
2230 PA_LLIST_FOREACH_SAFE(item, next, to_be_removed) {
2231 key.data = item->entry_name;
2232 key.size = strlen(item->entry_name);
2233
2234 pa_log_debug("Removing an invalid entry: %s", item->entry_name);
2235
2236 pa_assert_se(pa_database_unset(u->database, &key) >= 0);
2237 trigger_save(u);
2238
2239 PA_LLIST_REMOVE(struct clean_up_item, to_be_removed, item);
2240 pa_xfree(item->entry_name);
2241 pa_xfree(item);
2242 }
2243
2244 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
2245 PA_LLIST_FOREACH_SAFE(item, next, to_be_converted) {
2246 pa_log_debug("Upgrading a legacy entry to the current format: %s", item->entry_name);
2247
2248 pa_assert_se(entry_write(u, item->entry_name, item->entry, true));
2249 trigger_save(u);
2250
2251 PA_LLIST_REMOVE(struct clean_up_item, to_be_converted, item);
2252 pa_xfree(item->entry_name);
2253 entry_free(item->entry);
2254 pa_xfree(item);
2255 }
2256 #endif
2257 }
2258
pa__init(pa_module * m)2259 int pa__init(pa_module*m) {
2260 pa_modargs *ma = NULL;
2261 struct userdata *u;
2262 char *state_path;
2263 pa_sink_input *si;
2264 pa_source_output *so;
2265 uint32_t idx;
2266 bool restore_device = true, restore_volume = true, restore_muted = true;
2267
2268 #ifdef HAVE_DBUS
2269 pa_datum key;
2270 bool done;
2271 #endif
2272
2273 pa_assert(m);
2274
2275 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
2276 pa_log("Failed to parse module arguments");
2277 goto fail;
2278 }
2279
2280 if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 ||
2281 pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
2282 pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0) {
2283 pa_log("restore_device=, restore_volume= and restore_muted= expect boolean arguments");
2284 goto fail;
2285 }
2286
2287 if (pa_modargs_get_value(ma, "on_hotplug", NULL) != NULL ||
2288 pa_modargs_get_value(ma, "on_rescue", NULL) != NULL)
2289 pa_log("on_hotplug and on_rescue are obsolete arguments, please remove them from your configuration");
2290
2291 if (!restore_muted && !restore_volume && !restore_device)
2292 pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring device enabled!");
2293
2294 m->userdata = u = pa_xnew0(struct userdata, 1);
2295 u->core = m->core;
2296 u->module = m;
2297 u->restore_device = restore_device;
2298 u->restore_volume = restore_volume;
2299 u->restore_muted = restore_muted;
2300 u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
2301
2302 u->protocol = pa_native_protocol_get(m->core);
2303 pa_native_protocol_install_ext(u->protocol, m, extension_cb);
2304
2305 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);
2306
2307 u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u);
2308
2309 if (restore_device) {
2310 /* A little bit earlier than module-intended-roles ... */
2311 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);
2312 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);
2313 }
2314
2315 if (restore_volume || restore_muted) {
2316 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);
2317 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);
2318 }
2319
2320 if (!(state_path = pa_state_path(NULL, true)))
2321 goto fail;
2322
2323 if (!(u->database = pa_database_open(state_path, "stream-volumes", true, true))) {
2324 pa_xfree(state_path);
2325 goto fail;
2326 }
2327
2328 pa_xfree(state_path);
2329
2330 clean_up_db(u);
2331
2332 if (fill_db(u, pa_modargs_get_value(ma, "fallback_table", NULL)) < 0)
2333 goto fail;
2334
2335 #ifdef HAVE_DBUS
2336 u->dbus_protocol = pa_dbus_protocol_get(u->core);
2337 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);
2338
2339 pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, OBJECT_PATH, &stream_restore_interface_info, u) >= 0);
2340 pa_assert_se(pa_dbus_protocol_register_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2341
2342 /* Create the initial dbus entries. */
2343 done = !pa_database_first(u->database, &key, NULL);
2344 while (!done) {
2345 pa_datum next_key;
2346 char *name;
2347 struct dbus_entry *de;
2348
2349 name = pa_xstrndup(key.data, key.size);
2350 de = dbus_entry_new(u, name);
2351 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
2352 pa_xfree(name);
2353
2354 done = !pa_database_next(u->database, &key, &next_key, NULL);
2355 pa_datum_free(&key);
2356 key = next_key;
2357 }
2358 #endif
2359
2360 PA_IDXSET_FOREACH(si, m->core->sink_inputs, idx)
2361 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, si->index, u);
2362
2363 PA_IDXSET_FOREACH(so, m->core->source_outputs, idx)
2364 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, so->index, u);
2365
2366 pa_modargs_free(ma);
2367 return 0;
2368
2369 fail:
2370 pa__done(m);
2371
2372 if (ma)
2373 pa_modargs_free(ma);
2374
2375 return -1;
2376 }
2377
pa__done(pa_module * m)2378 void pa__done(pa_module*m) {
2379 struct userdata* u;
2380
2381 pa_assert(m);
2382
2383 if (!(u = m->userdata))
2384 return;
2385
2386 #ifdef HAVE_DBUS
2387 if (u->dbus_protocol) {
2388 pa_assert(u->dbus_entries);
2389
2390 pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2391 pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, OBJECT_PATH, stream_restore_interface_info.name) >= 0);
2392
2393 pa_hashmap_free(u->dbus_entries);
2394
2395 pa_dbus_protocol_unref(u->dbus_protocol);
2396 }
2397 #endif
2398
2399 if (u->subscription)
2400 pa_subscription_free(u->subscription);
2401
2402 if (u->save_time_event)
2403 u->core->mainloop->time_free(u->save_time_event);
2404
2405 if (u->database)
2406 pa_database_close(u->database);
2407
2408 if (u->protocol) {
2409 pa_native_protocol_remove_ext(u->protocol, m);
2410 pa_native_protocol_unref(u->protocol);
2411 }
2412
2413 if (u->subscribed)
2414 pa_idxset_free(u->subscribed, NULL);
2415
2416 pa_xfree(u);
2417 }
2418