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