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