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