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