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