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