]> code.delx.au - pulseaudio/blob - src/modules/module-stream-restore.c
capture: Add the passthrough format negotiation to capture streams.
[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, de) >= 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 (!PA_VOLUME_IS_VALID(chan_vol)) {
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->version = ENTRY_VERSION;
654 e->muted_valid = TRUE;
655 e->volume_valid = !!map.channels;
656 e->device_valid = !!device[0];
657 e->muted = muted;
658 e->volume = vol;
659 e->channel_map = map;
660 pa_strlcpy(e->device, device, sizeof(e->device));
661
662 send_new_entry_signal(dbus_entry);
663 }
664
665 key.data = (char *) name;
666 key.size = strlen(name);
667
668 value.data = e;
669 value.size = sizeof(struct entry);
670
671 pa_assert_se(pa_database_set(u->database, &key, &value, TRUE) == 0);
672 if (apply_immediately)
673 apply_entry(u, name, e);
674
675 trigger_save(u);
676
677 pa_dbus_send_empty_reply(conn, msg);
678
679 pa_xfree(e);
680 }
681
682 static void handle_get_entry_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
683 struct userdata *u = userdata;
684 const char *name;
685 struct dbus_entry *de;
686
687 pa_assert(conn);
688 pa_assert(msg);
689 pa_assert(u);
690
691 pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID));
692
693 if (!(de = pa_hashmap_get(u->dbus_entries, name))) {
694 pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such stream restore entry.");
695 return;
696 }
697
698 pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &de->object_path);
699 }
700
701 static void handle_entry_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
702 struct dbus_entry *de = userdata;
703
704 pa_assert(conn);
705 pa_assert(msg);
706 pa_assert(de);
707
708 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &de->index);
709 }
710
711 static void handle_entry_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
712 struct dbus_entry *de = userdata;
713
714 pa_assert(conn);
715 pa_assert(msg);
716 pa_assert(de);
717
718 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &de->entry_name);
719 }
720
721 static void handle_entry_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
722 struct dbus_entry *de = userdata;
723 struct entry *e;
724 const char *device;
725
726 pa_assert(conn);
727 pa_assert(msg);
728 pa_assert(de);
729
730 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
731
732 device = e->device_valid ? e->device : "";
733
734 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &device);
735
736 pa_xfree(e);
737 }
738
739 static void handle_entry_set_device(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
740 struct dbus_entry *de = userdata;
741 const char *device;
742 struct entry *e;
743 pa_bool_t updated;
744
745 pa_assert(conn);
746 pa_assert(msg);
747 pa_assert(iter);
748 pa_assert(de);
749
750 dbus_message_iter_get_basic(iter, &device);
751
752 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
753
754 updated = (e->device_valid != !!device[0]) || !pa_streq(e->device, device);
755
756 if (updated) {
757 pa_datum key;
758 pa_datum value;
759
760 pa_strlcpy(e->device, device, sizeof(e->device));
761 e->device_valid = !!device[0];
762
763 key.data = de->entry_name;
764 key.size = strlen(de->entry_name);
765 value.data = e;
766 value.size = sizeof(struct entry);
767 pa_assert_se(pa_database_set(de->userdata->database, &key, &value, TRUE) == 0);
768
769 apply_entry(de->userdata, de->entry_name, e);
770 send_device_updated_signal(de, e);
771 trigger_save(de->userdata);
772 }
773
774 pa_dbus_send_empty_reply(conn, msg);
775
776 pa_xfree(e);
777 }
778
779 static void handle_entry_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
780 struct dbus_entry *de = userdata;
781 DBusMessage *reply;
782 DBusMessageIter msg_iter;
783 struct entry *e;
784
785 pa_assert(conn);
786 pa_assert(msg);
787 pa_assert(de);
788
789 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
790
791 pa_assert_se(reply = dbus_message_new_method_return(msg));
792
793 dbus_message_iter_init_append(reply, &msg_iter);
794 append_volume_variant(&msg_iter, e);
795
796 pa_assert_se(dbus_connection_send(conn, reply, NULL));
797
798 pa_xfree(e);
799 }
800
801 static void handle_entry_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
802 struct dbus_entry *de = userdata;
803 pa_channel_map map;
804 pa_cvolume vol;
805 struct entry *e = NULL;
806 pa_bool_t updated = FALSE;
807
808 pa_assert(conn);
809 pa_assert(msg);
810 pa_assert(iter);
811 pa_assert(de);
812
813 if (get_volume_arg(conn, msg, iter, &map, &vol) < 0)
814 return;
815
816 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
817
818 updated = (e->volume_valid != !!map.channels) || !pa_cvolume_equal(&e->volume, &vol);
819
820 if (updated) {
821 pa_datum key;
822 pa_datum value;
823
824 e->volume = vol;
825 e->channel_map = map;
826 e->volume_valid = !!map.channels;
827
828 key.data = de->entry_name;
829 key.size = strlen(de->entry_name);
830 value.data = e;
831 value.size = sizeof(struct entry);
832 pa_assert_se(pa_database_set(de->userdata->database, &key, &value, TRUE) == 0);
833
834 apply_entry(de->userdata, de->entry_name, e);
835 send_volume_updated_signal(de, e);
836 trigger_save(de->userdata);
837 }
838
839 pa_dbus_send_empty_reply(conn, msg);
840
841 pa_xfree(e);
842 }
843
844 static void handle_entry_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
845 struct dbus_entry *de = userdata;
846 struct entry *e;
847 dbus_bool_t mute;
848
849 pa_assert(conn);
850 pa_assert(msg);
851 pa_assert(de);
852
853 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
854
855 mute = e->muted_valid ? e->muted : FALSE;
856
857 pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &mute);
858
859 pa_xfree(e);
860 }
861
862 static void handle_entry_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
863 struct dbus_entry *de = userdata;
864 dbus_bool_t mute;
865 struct entry *e;
866 pa_bool_t updated;
867
868 pa_assert(conn);
869 pa_assert(msg);
870 pa_assert(iter);
871 pa_assert(de);
872
873 dbus_message_iter_get_basic(iter, &mute);
874
875 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
876
877 updated = !e->muted_valid || e->muted != mute;
878
879 if (updated) {
880 pa_datum key;
881 pa_datum value;
882
883 e->muted = mute;
884 e->muted_valid = TRUE;
885
886 key.data = de->entry_name;
887 key.size = strlen(de->entry_name);
888 value.data = e;
889 value.size = sizeof(struct entry);
890 pa_assert_se(pa_database_set(de->userdata->database, &key, &value, TRUE) == 0);
891
892 apply_entry(de->userdata, de->entry_name, e);
893 send_mute_updated_signal(de, e);
894 trigger_save(de->userdata);
895 }
896
897 pa_dbus_send_empty_reply(conn, msg);
898
899 pa_xfree(e);
900 }
901
902 static void handle_entry_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
903 struct dbus_entry *de = userdata;
904 struct entry *e;
905 DBusMessage *reply = NULL;
906 DBusMessageIter msg_iter;
907 DBusMessageIter dict_iter;
908 DBusMessageIter dict_entry_iter;
909 const char *device;
910 dbus_bool_t mute;
911
912 pa_assert(conn);
913 pa_assert(msg);
914 pa_assert(de);
915
916 pa_assert_se(e = read_entry(de->userdata, de->entry_name));
917
918 device = e->device_valid ? e->device : "";
919 mute = e->muted_valid ? e->muted : FALSE;
920
921 pa_assert_se((reply = dbus_message_new_method_return(msg)));
922
923 dbus_message_iter_init_append(reply, &msg_iter);
924 pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
925
926 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &de->index);
927 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &de->entry_name);
928 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_DEVICE].property_name, DBUS_TYPE_STRING, &device);
929
930 pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
931
932 pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &entry_property_handlers[ENTRY_PROPERTY_HANDLER_VOLUME].property_name));
933 append_volume_variant(&dict_entry_iter, e);
934
935 pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
936
937 pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &mute);
938
939 pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
940
941 pa_assert_se(dbus_connection_send(conn, reply, NULL));
942
943 dbus_message_unref(reply);
944
945 pa_xfree(e);
946 }
947
948 static void handle_entry_remove(DBusConnection *conn, DBusMessage *msg, void *userdata) {
949 struct dbus_entry *de = userdata;
950 pa_datum key;
951
952 pa_assert(conn);
953 pa_assert(msg);
954 pa_assert(de);
955
956 key.data = de->entry_name;
957 key.size = strlen(de->entry_name);
958
959 pa_assert_se(pa_database_unset(de->userdata->database, &key) == 0);
960
961 send_entry_removed_signal(de);
962 trigger_save(de->userdata);
963
964 pa_assert_se(pa_hashmap_remove(de->userdata->dbus_entries, de->entry_name));
965 dbus_entry_free(de);
966
967 pa_dbus_send_empty_reply(conn, msg);
968 }
969
970 #endif /* HAVE_DBUS */
971
972 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
973 struct userdata *u = userdata;
974
975 pa_assert(a);
976 pa_assert(e);
977 pa_assert(u);
978
979 pa_assert(e == u->save_time_event);
980 u->core->mainloop->time_free(u->save_time_event);
981 u->save_time_event = NULL;
982
983 pa_database_sync(u->database);
984 pa_log_info("Synced.");
985 }
986
987 static char *get_name(pa_proplist *p, const char *prefix) {
988 const char *r;
989 char *t;
990
991 if (!p)
992 return NULL;
993
994 if ((r = pa_proplist_gets(p, IDENTIFICATION_PROPERTY)))
995 return pa_xstrdup(r);
996
997 if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE)))
998 t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
999 else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID)))
1000 t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
1001 else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME)))
1002 t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
1003 else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
1004 t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
1005 else
1006 t = pa_sprintf_malloc("%s-fallback:%s", prefix, r);
1007
1008 pa_proplist_sets(p, IDENTIFICATION_PROPERTY, t);
1009 return t;
1010 }
1011
1012 static struct entry *read_entry(struct userdata *u, const char *name) {
1013 pa_datum key, data;
1014 struct entry *e;
1015
1016 pa_assert(u);
1017 pa_assert(name);
1018
1019 key.data = (char*) name;
1020 key.size = strlen(name);
1021
1022 pa_zero(data);
1023
1024 if (!pa_database_get(u->database, &key, &data))
1025 goto fail;
1026
1027 if (data.size != sizeof(struct entry)) {
1028 /* This is probably just a database upgrade, hence let's not
1029 * consider this more than a debug message */
1030 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));
1031 goto fail;
1032 }
1033
1034 e = (struct entry*) data.data;
1035
1036 if (e->version != ENTRY_VERSION) {
1037 pa_log_debug("Version of database entry for stream %s doesn't match our version. Probably due to upgrade, ignoring.", name);
1038 goto fail;
1039 }
1040
1041 if (!memchr(e->device, 0, sizeof(e->device))) {
1042 pa_log_warn("Database contains entry for stream %s with missing NUL byte in device name", name);
1043 goto fail;
1044 }
1045
1046 if (!memchr(e->card, 0, sizeof(e->card))) {
1047 pa_log_warn("Database contains entry for stream %s with missing NUL byte in card name", name);
1048 goto fail;
1049 }
1050
1051 if (e->device_valid && !pa_namereg_is_valid_name(e->device)) {
1052 pa_log_warn("Invalid device name stored in database for stream %s", name);
1053 goto fail;
1054 }
1055
1056 if (e->card_valid && !pa_namereg_is_valid_name(e->card)) {
1057 pa_log_warn("Invalid card name stored in database for stream %s", name);
1058 goto fail;
1059 }
1060
1061 if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
1062 pa_log_warn("Invalid channel map stored in database for stream %s", name);
1063 goto fail;
1064 }
1065
1066 if (e->volume_valid && (!pa_cvolume_valid(&e->volume) || !pa_cvolume_compatible_with_channel_map(&e->volume, &e->channel_map))) {
1067 pa_log_warn("Invalid volume stored in database for stream %s", name);
1068 goto fail;
1069 }
1070
1071 return e;
1072
1073 fail:
1074
1075 pa_datum_free(&data);
1076 return NULL;
1077 }
1078
1079 static void trigger_save(struct userdata *u) {
1080 pa_native_connection *c;
1081 uint32_t idx;
1082
1083 for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(u->subscribed, &idx)) {
1084 pa_tagstruct *t;
1085
1086 t = pa_tagstruct_new(NULL, 0);
1087 pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
1088 pa_tagstruct_putu32(t, 0);
1089 pa_tagstruct_putu32(t, u->module->index);
1090 pa_tagstruct_puts(t, u->module->name);
1091 pa_tagstruct_putu32(t, SUBCOMMAND_EVENT);
1092
1093 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t);
1094 }
1095
1096 if (u->save_time_event)
1097 return;
1098
1099 u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
1100 }
1101
1102 static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
1103 pa_cvolume t;
1104
1105 pa_assert(a);
1106 pa_assert(b);
1107
1108 if (a->device_valid != b->device_valid ||
1109 (a->device_valid && strncmp(a->device, b->device, sizeof(a->device))))
1110 return FALSE;
1111
1112 if (a->card_valid != b->card_valid ||
1113 (a->card_valid && strncmp(a->card, b->card, sizeof(a->card))))
1114 return FALSE;
1115
1116 if (a->muted_valid != b->muted_valid ||
1117 (a->muted_valid && (a->muted != b->muted)))
1118 return FALSE;
1119
1120 t = b->volume;
1121 if (a->volume_valid != b->volume_valid ||
1122 (a->volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->volume)))
1123 return FALSE;
1124
1125 return TRUE;
1126 }
1127
1128 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
1129 struct userdata *u = userdata;
1130 struct entry entry, *old = NULL;
1131 char *name = NULL;
1132 pa_datum key, data;
1133
1134 /* These are only used when D-Bus is enabled, but in order to reduce ifdef
1135 * clutter these are defined here unconditionally. */
1136 pa_bool_t created_new_entry = TRUE;
1137 pa_bool_t device_updated = FALSE;
1138 pa_bool_t volume_updated = FALSE;
1139 pa_bool_t mute_updated = FALSE;
1140
1141 #ifdef HAVE_DBUS
1142 struct dbus_entry *de = NULL;
1143 #endif
1144
1145 pa_assert(c);
1146 pa_assert(u);
1147
1148 if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW) &&
1149 t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) &&
1150 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW) &&
1151 t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
1152 return;
1153
1154 pa_zero(entry);
1155 entry.version = ENTRY_VERSION;
1156
1157 if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
1158 pa_sink_input *sink_input;
1159
1160 if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx)))
1161 return;
1162
1163 if (!(name = get_name(sink_input->proplist, "sink-input")))
1164 return;
1165
1166 if ((old = read_entry(u, name))) {
1167 entry = *old;
1168 created_new_entry = FALSE;
1169 }
1170
1171 if (sink_input->save_volume && pa_sink_input_is_volume_readable(sink_input)) {
1172 pa_assert(sink_input->volume_writable);
1173
1174 entry.channel_map = sink_input->channel_map;
1175 pa_sink_input_get_volume(sink_input, &entry.volume, FALSE);
1176 entry.volume_valid = TRUE;
1177
1178 volume_updated = !created_new_entry
1179 && (!old->volume_valid
1180 || !pa_channel_map_equal(&entry.channel_map, &old->channel_map)
1181 || !pa_cvolume_equal(&entry.volume, &old->volume));
1182 }
1183
1184 if (sink_input->save_muted) {
1185 entry.muted = pa_sink_input_get_mute(sink_input);
1186 entry.muted_valid = TRUE;
1187
1188 mute_updated = !created_new_entry && (!old->muted_valid || entry.muted != old->muted);
1189 }
1190
1191 if (sink_input->save_sink) {
1192 pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device));
1193 entry.device_valid = TRUE;
1194
1195 device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry.device, old->device));
1196 if (sink_input->sink->card) {
1197 pa_strlcpy(entry.card, sink_input->sink->card->name, sizeof(entry.card));
1198 entry.card_valid = TRUE;
1199 }
1200 }
1201
1202 } else {
1203 pa_source_output *source_output;
1204
1205 pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT);
1206
1207 if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx)))
1208 return;
1209
1210 if (!(name = get_name(source_output->proplist, "source-output")))
1211 return;
1212
1213 if ((old = read_entry(u, name))) {
1214 entry = *old;
1215 created_new_entry = FALSE;
1216 }
1217
1218 if (source_output->save_source) {
1219 pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device));
1220 entry.device_valid = TRUE;
1221
1222 device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry.device, old->device));
1223
1224 if (source_output->source->card) {
1225 pa_strlcpy(entry.card, source_output->source->card->name, sizeof(entry.card));
1226 entry.card_valid = TRUE;
1227 }
1228 }
1229 }
1230
1231 if (old) {
1232
1233 if (entries_equal(old, &entry)) {
1234 pa_xfree(old);
1235 pa_xfree(name);
1236 return;
1237 }
1238
1239 pa_xfree(old);
1240 }
1241
1242 key.data = name;
1243 key.size = strlen(name);
1244
1245 data.data = &entry;
1246 data.size = sizeof(entry);
1247
1248 pa_log_info("Storing volume/mute/device for stream %s.", name);
1249
1250 pa_database_set(u->database, &key, &data, TRUE);
1251
1252 #ifdef HAVE_DBUS
1253 if (created_new_entry) {
1254 de = dbus_entry_new(u, name);
1255 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
1256 send_new_entry_signal(de);
1257 } else {
1258 pa_assert_se(de = pa_hashmap_get(u->dbus_entries, name));
1259
1260 if (device_updated)
1261 send_device_updated_signal(de, &entry);
1262 if (volume_updated)
1263 send_volume_updated_signal(de, &entry);
1264 if (mute_updated)
1265 send_mute_updated_signal(de, &entry);
1266 }
1267 #endif
1268
1269 pa_xfree(name);
1270
1271 trigger_save(u);
1272 }
1273
1274 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1275 char *name;
1276 struct entry *e;
1277
1278 pa_assert(c);
1279 pa_assert(new_data);
1280 pa_assert(u);
1281 pa_assert(u->restore_device);
1282
1283 if (!(name = get_name(new_data->proplist, "sink-input")))
1284 return PA_HOOK_OK;
1285
1286 if (new_data->sink)
1287 pa_log_debug("Not restoring device for stream %s, because already set to '%s'.", name, new_data->sink->name);
1288 else if ((e = read_entry(u, name))) {
1289 pa_sink *s = NULL;
1290
1291 if (e->device_valid)
1292 s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK);
1293
1294 if (!s && e->card_valid) {
1295 pa_card *card;
1296
1297 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1298 s = pa_idxset_first(card->sinks, NULL);
1299 }
1300
1301 /* It might happen that a stream and a sink are set up at the
1302 same time, in which case we want to make sure we don't
1303 interfere with that */
1304 if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s)))
1305 if (pa_sink_input_new_data_set_sink(new_data, s, TRUE))
1306 pa_log_info("Restoring device for stream %s.", name);
1307
1308 pa_xfree(e);
1309 }
1310
1311 pa_xfree(name);
1312
1313 return PA_HOOK_OK;
1314 }
1315
1316 static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1317 char *name;
1318 struct entry *e;
1319
1320 pa_assert(c);
1321 pa_assert(new_data);
1322 pa_assert(u);
1323 pa_assert(u->restore_volume || u->restore_muted);
1324
1325 if (!(name = get_name(new_data->proplist, "sink-input")))
1326 return PA_HOOK_OK;
1327
1328 if ((e = read_entry(u, name))) {
1329
1330 if (u->restore_volume && e->volume_valid) {
1331 if (!new_data->volume_writable)
1332 pa_log_debug("Not restoring volume for sink input %s, because its volume can't be changed.", name);
1333 else if (new_data->volume_is_set)
1334 pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
1335 else {
1336 pa_cvolume v;
1337
1338 pa_log_info("Restoring volume for sink input %s.", name);
1339
1340 v = e->volume;
1341 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
1342 pa_sink_input_new_data_set_volume(new_data, &v);
1343
1344 new_data->volume_is_absolute = FALSE;
1345 new_data->save_volume = TRUE;
1346 }
1347 }
1348
1349 if (u->restore_muted && e->muted_valid) {
1350
1351 if (!new_data->muted_is_set) {
1352 pa_log_info("Restoring mute state for sink input %s.", name);
1353 pa_sink_input_new_data_set_muted(new_data, e->muted);
1354 new_data->save_muted = TRUE;
1355 } else
1356 pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
1357 }
1358
1359 pa_xfree(e);
1360 }
1361
1362 pa_xfree(name);
1363
1364 return PA_HOOK_OK;
1365 }
1366
1367 static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
1368 char *name;
1369 struct entry *e;
1370
1371 pa_assert(c);
1372 pa_assert(new_data);
1373 pa_assert(u);
1374 pa_assert(u->restore_device);
1375
1376 if (new_data->direct_on_input)
1377 return PA_HOOK_OK;
1378
1379 if (!(name = get_name(new_data->proplist, "source-output")))
1380 return PA_HOOK_OK;
1381
1382 if (new_data->source)
1383 pa_log_debug("Not restoring device for stream %s, because already set", name);
1384 else if ((e = read_entry(u, name))) {
1385 pa_source *s = NULL;
1386
1387 if (e->device_valid)
1388 s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE);
1389
1390 if (!s && e->card_valid) {
1391 pa_card *card;
1392
1393 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1394 s = pa_idxset_first(card->sources, NULL);
1395 }
1396
1397 /* It might happen that a stream and a sink are set up at the
1398 same time, in which case we want to make sure we don't
1399 interfere with that */
1400 if (s && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) {
1401 pa_log_info("Restoring device for stream %s.", name);
1402 pa_source_output_new_data_set_source(new_data, s, TRUE);
1403 }
1404
1405 pa_xfree(e);
1406 }
1407
1408 pa_xfree(name);
1409
1410 return PA_HOOK_OK;
1411 }
1412
1413 static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
1414 pa_sink_input *si;
1415 uint32_t idx;
1416
1417 pa_assert(c);
1418 pa_assert(sink);
1419 pa_assert(u);
1420 pa_assert(u->on_hotplug && u->restore_device);
1421
1422 PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
1423 char *name;
1424 struct entry *e;
1425
1426 if (si->sink == sink)
1427 continue;
1428
1429 if (si->save_sink)
1430 continue;
1431
1432 /* Skip this if it is already in the process of being moved
1433 * anyway */
1434 if (!si->sink)
1435 continue;
1436
1437 /* It might happen that a stream and a sink are set up at the
1438 same time, in which case we want to make sure we don't
1439 interfere with that */
1440 if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si)))
1441 continue;
1442
1443 if (!(name = get_name(si->proplist, "sink-input")))
1444 continue;
1445
1446 if ((e = read_entry(u, name))) {
1447 if (e->device_valid && pa_streq(e->device, sink->name))
1448 pa_sink_input_move_to(si, sink, TRUE);
1449
1450 pa_xfree(e);
1451 }
1452
1453 pa_xfree(name);
1454 }
1455
1456 return PA_HOOK_OK;
1457 }
1458
1459 static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
1460 pa_source_output *so;
1461 uint32_t idx;
1462
1463 pa_assert(c);
1464 pa_assert(source);
1465 pa_assert(u);
1466 pa_assert(u->on_hotplug && u->restore_device);
1467
1468 PA_IDXSET_FOREACH(so, c->source_outputs, idx) {
1469 char *name;
1470 struct entry *e;
1471
1472 if (so->source == source)
1473 continue;
1474
1475 if (so->save_source)
1476 continue;
1477
1478 if (so->direct_on_input)
1479 continue;
1480
1481 /* Skip this if it is already in the process of being moved anyway */
1482 if (!so->source)
1483 continue;
1484
1485 /* It might happen that a stream and a source are set up at the
1486 same time, in which case we want to make sure we don't
1487 interfere with that */
1488 if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(so)))
1489 continue;
1490
1491 if (!(name = get_name(so->proplist, "source-output")))
1492 continue;
1493
1494 if ((e = read_entry(u, name))) {
1495 if (e->device_valid && pa_streq(e->device, source->name))
1496 pa_source_output_move_to(so, source, TRUE);
1497
1498 pa_xfree(e);
1499 }
1500
1501 pa_xfree(name);
1502 }
1503
1504 return PA_HOOK_OK;
1505 }
1506
1507 static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
1508 pa_sink_input *si;
1509 uint32_t idx;
1510
1511 pa_assert(c);
1512 pa_assert(sink);
1513 pa_assert(u);
1514 pa_assert(u->on_rescue && u->restore_device);
1515
1516 /* There's no point in doing anything if the core is shut down anyway */
1517 if (c->state == PA_CORE_SHUTDOWN)
1518 return PA_HOOK_OK;
1519
1520 PA_IDXSET_FOREACH(si, sink->inputs, idx) {
1521 char *name;
1522 struct entry *e;
1523
1524 if (!si->sink)
1525 continue;
1526
1527 if (!(name = get_name(si->proplist, "sink-input")))
1528 continue;
1529
1530 if ((e = read_entry(u, name))) {
1531
1532 if (e->device_valid) {
1533 pa_sink *d;
1534
1535 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) &&
1536 d != sink &&
1537 PA_SINK_IS_LINKED(pa_sink_get_state(d)))
1538 pa_sink_input_move_to(si, d, TRUE);
1539 }
1540
1541 pa_xfree(e);
1542 }
1543
1544 pa_xfree(name);
1545 }
1546
1547 return PA_HOOK_OK;
1548 }
1549
1550 static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
1551 pa_source_output *so;
1552 uint32_t idx;
1553
1554 pa_assert(c);
1555 pa_assert(source);
1556 pa_assert(u);
1557 pa_assert(u->on_rescue && u->restore_device);
1558
1559 /* There's no point in doing anything if the core is shut down anyway */
1560 if (c->state == PA_CORE_SHUTDOWN)
1561 return PA_HOOK_OK;
1562
1563 PA_IDXSET_FOREACH(so, source->outputs, idx) {
1564 char *name;
1565 struct entry *e;
1566
1567 if (so->direct_on_input)
1568 continue;
1569
1570 if (!so->source)
1571 continue;
1572
1573 if (!(name = get_name(so->proplist, "source-output")))
1574 continue;
1575
1576 if ((e = read_entry(u, name))) {
1577
1578 if (e->device_valid) {
1579 pa_source *d;
1580
1581 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE)) &&
1582 d != source &&
1583 PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
1584 pa_source_output_move_to(so, d, TRUE);
1585 }
1586
1587 pa_xfree(e);
1588 }
1589
1590 pa_xfree(name);
1591 }
1592
1593 return PA_HOOK_OK;
1594 }
1595
1596 #define EXT_VERSION 1
1597
1598 static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
1599 pa_sink_input *si;
1600 pa_source_output *so;
1601 uint32_t idx;
1602
1603 pa_assert(u);
1604 pa_assert(name);
1605 pa_assert(e);
1606
1607 PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
1608 char *n;
1609 pa_sink *s;
1610
1611 if (!(n = get_name(si->proplist, "sink-input")))
1612 continue;
1613
1614 if (!pa_streq(name, n)) {
1615 pa_xfree(n);
1616 continue;
1617 }
1618 pa_xfree(n);
1619
1620 if (u->restore_volume && e->volume_valid && si->volume_writable) {
1621 pa_cvolume v;
1622
1623 v = e->volume;
1624 pa_log_info("Restoring volume for sink input %s.", name);
1625 pa_cvolume_remap(&v, &e->channel_map, &si->channel_map);
1626 pa_sink_input_set_volume(si, &v, TRUE, FALSE);
1627 }
1628
1629 if (u->restore_muted && e->muted_valid) {
1630 pa_log_info("Restoring mute state for sink input %s.", name);
1631 pa_sink_input_set_mute(si, e->muted, TRUE);
1632 }
1633
1634 if (u->restore_device) {
1635 if (!e->device_valid) {
1636 if (si->save_sink) {
1637 pa_log_info("Ensuring device is not saved for stream %s.", name);
1638 /* If the device is not valid we should make sure the
1639 save flag is cleared as the user may have specifically
1640 removed the sink element from the rule. */
1641 si->save_sink = FALSE;
1642 /* This is cheating a bit. The sink input itself has not changed
1643 but the rules governing it's routing have, so we fire this event
1644 such that other routing modules (e.g. module-device-manager)
1645 will pick up the change and reapply their routing */
1646 pa_subscription_post(si->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, si->index);
1647 }
1648 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) {
1649 pa_log_info("Restoring device for stream %s.", name);
1650 pa_sink_input_move_to(si, s, TRUE);
1651 }
1652 }
1653 }
1654
1655 PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
1656 char *n;
1657 pa_source *s;
1658
1659 if (!(n = get_name(so->proplist, "source-output")))
1660 continue;
1661
1662 if (!pa_streq(name, n)) {
1663 pa_xfree(n);
1664 continue;
1665 }
1666 pa_xfree(n);
1667
1668 if (u->restore_device) {
1669 if (!e->device_valid) {
1670 if (so->save_source) {
1671 pa_log_info("Ensuring device is not saved for stream %s.", name);
1672 /* If the device is not valid we should make sure the
1673 save flag is cleared as the user may have specifically
1674 removed the source element from the rule. */
1675 so->save_source = FALSE;
1676 /* This is cheating a bit. The source output itself has not changed
1677 but the rules governing it's routing have, so we fire this event
1678 such that other routing modules (e.g. module-device-manager)
1679 will pick up the change and reapply their routing */
1680 pa_subscription_post(so->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, so->index);
1681 }
1682 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
1683 pa_log_info("Restoring device for stream %s.", name);
1684 pa_source_output_move_to(so, s, TRUE);
1685 }
1686 }
1687 }
1688 }
1689
1690 #ifdef DEBUG_VOLUME
1691 PA_GCC_UNUSED static void stream_restore_dump_database(struct userdata *u) {
1692 pa_datum key;
1693 pa_bool_t done;
1694
1695 done = !pa_database_first(u->database, &key, NULL);
1696
1697 while (!done) {
1698 pa_datum next_key;
1699 struct entry *e;
1700 char *name;
1701
1702 done = !pa_database_next(u->database, &key, &next_key, NULL);
1703
1704 name = pa_xstrndup(key.data, key.size);
1705 pa_datum_free(&key);
1706
1707 if ((e = read_entry(u, name))) {
1708 char t[256];
1709 pa_log("name=%s", name);
1710 pa_log("device=%s %s", e->device, pa_yes_no(e->device_valid));
1711 pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map));
1712 pa_log("volume=%s %s", pa_cvolume_snprint(t, sizeof(t), &e->volume), pa_yes_no(e->volume_valid));
1713 pa_log("mute=%s %s", pa_yes_no(e->muted), pa_yes_no(e->volume_valid));
1714 pa_xfree(e);
1715 }
1716
1717 pa_xfree(name);
1718
1719 key = next_key;
1720 }
1721 }
1722 #endif
1723
1724 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
1725 struct userdata *u;
1726 uint32_t command;
1727 pa_tagstruct *reply = NULL;
1728
1729 pa_assert(p);
1730 pa_assert(m);
1731 pa_assert(c);
1732 pa_assert(t);
1733
1734 u = m->userdata;
1735
1736 if (pa_tagstruct_getu32(t, &command) < 0)
1737 goto fail;
1738
1739 reply = pa_tagstruct_new(NULL, 0);
1740 pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
1741 pa_tagstruct_putu32(reply, tag);
1742
1743 switch (command) {
1744 case SUBCOMMAND_TEST: {
1745 if (!pa_tagstruct_eof(t))
1746 goto fail;
1747
1748 pa_tagstruct_putu32(reply, EXT_VERSION);
1749 break;
1750 }
1751
1752 case SUBCOMMAND_READ: {
1753 pa_datum key;
1754 pa_bool_t done;
1755
1756 if (!pa_tagstruct_eof(t))
1757 goto fail;
1758
1759 done = !pa_database_first(u->database, &key, NULL);
1760
1761 while (!done) {
1762 pa_datum next_key;
1763 struct entry *e;
1764 char *name;
1765
1766 done = !pa_database_next(u->database, &key, &next_key, NULL);
1767
1768 name = pa_xstrndup(key.data, key.size);
1769 pa_datum_free(&key);
1770
1771 if ((e = read_entry(u, name))) {
1772 pa_cvolume r;
1773 pa_channel_map cm;
1774
1775 pa_tagstruct_puts(reply, name);
1776 pa_tagstruct_put_channel_map(reply, e->volume_valid ? &e->channel_map : pa_channel_map_init(&cm));
1777 pa_tagstruct_put_cvolume(reply, e->volume_valid ? &e->volume : pa_cvolume_init(&r));
1778 pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
1779 pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
1780
1781 pa_xfree(e);
1782 }
1783
1784 pa_xfree(name);
1785
1786 key = next_key;
1787 }
1788
1789 break;
1790 }
1791
1792 case SUBCOMMAND_WRITE: {
1793 uint32_t mode;
1794 pa_bool_t apply_immediately = FALSE;
1795
1796 if (pa_tagstruct_getu32(t, &mode) < 0 ||
1797 pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
1798 goto fail;
1799
1800 if (mode != PA_UPDATE_MERGE &&
1801 mode != PA_UPDATE_REPLACE &&
1802 mode != PA_UPDATE_SET)
1803 goto fail;
1804
1805 if (mode == PA_UPDATE_SET) {
1806 #ifdef HAVE_DBUS
1807 struct dbus_entry *de;
1808 void *state = NULL;
1809
1810 PA_HASHMAP_FOREACH(de, u->dbus_entries, state) {
1811 send_entry_removed_signal(de);
1812 dbus_entry_free(pa_hashmap_remove(u->dbus_entries, de->entry_name));
1813 }
1814 #endif
1815 pa_database_clear(u->database);
1816 }
1817
1818 while (!pa_tagstruct_eof(t)) {
1819 const char *name, *device;
1820 pa_bool_t muted;
1821 struct entry entry;
1822 pa_datum key, data;
1823 #ifdef HAVE_DBUS
1824 struct entry *old;
1825 #endif
1826
1827 pa_zero(entry);
1828 entry.version = ENTRY_VERSION;
1829
1830 if (pa_tagstruct_gets(t, &name) < 0 ||
1831 pa_tagstruct_get_channel_map(t, &entry.channel_map) ||
1832 pa_tagstruct_get_cvolume(t, &entry.volume) < 0 ||
1833 pa_tagstruct_gets(t, &device) < 0 ||
1834 pa_tagstruct_get_boolean(t, &muted) < 0)
1835 goto fail;
1836
1837 if (!name || !*name)
1838 goto fail;
1839
1840 entry.volume_valid = entry.volume.channels > 0;
1841
1842 if (entry.volume_valid)
1843 if (!pa_cvolume_compatible_with_channel_map(&entry.volume, &entry.channel_map))
1844 goto fail;
1845
1846 entry.muted = muted;
1847 entry.muted_valid = TRUE;
1848
1849 if (device)
1850 pa_strlcpy(entry.device, device, sizeof(entry.device));
1851 entry.device_valid = !!entry.device[0];
1852
1853 if (entry.device_valid &&
1854 !pa_namereg_is_valid_name(entry.device))
1855 goto fail;
1856
1857 #ifdef HAVE_DBUS
1858 old = read_entry(u, name);
1859 #endif
1860
1861 key.data = (char*) name;
1862 key.size = strlen(name);
1863
1864 data.data = &entry;
1865 data.size = sizeof(entry);
1866
1867 pa_log_debug("Client %s changes entry %s.",
1868 pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)),
1869 name);
1870
1871 if (pa_database_set(u->database, &key, &data, mode == PA_UPDATE_REPLACE) == 0) {
1872 #ifdef HAVE_DBUS
1873 struct dbus_entry *de;
1874
1875 if (old) {
1876 pa_assert_se((de = pa_hashmap_get(u->dbus_entries, name)));
1877
1878 if ((old->device_valid != entry.device_valid)
1879 || (entry.device_valid && !pa_streq(entry.device, old->device)))
1880 send_device_updated_signal(de, &entry);
1881
1882 if ((old->volume_valid != entry.volume_valid)
1883 || (entry.volume_valid && (!pa_cvolume_equal(&entry.volume, &old->volume)
1884 || !pa_channel_map_equal(&entry.channel_map, &old->channel_map))))
1885 send_volume_updated_signal(de, &entry);
1886
1887 if (!old->muted_valid || (entry.muted != old->muted))
1888 send_mute_updated_signal(de, &entry);
1889
1890 } else {
1891 de = dbus_entry_new(u, name);
1892 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
1893 send_new_entry_signal(de);
1894 }
1895 #endif
1896
1897 if (apply_immediately)
1898 apply_entry(u, name, &entry);
1899 }
1900
1901 #ifdef HAVE_DBUS
1902 if (old)
1903 pa_xfree(old);
1904 #endif
1905 }
1906
1907 trigger_save(u);
1908
1909 break;
1910 }
1911
1912 case SUBCOMMAND_DELETE:
1913
1914 while (!pa_tagstruct_eof(t)) {
1915 const char *name;
1916 pa_datum key;
1917 #ifdef HAVE_DBUS
1918 struct dbus_entry *de;
1919 #endif
1920
1921 if (pa_tagstruct_gets(t, &name) < 0)
1922 goto fail;
1923
1924 #ifdef HAVE_DBUS
1925 if ((de = pa_hashmap_get(u->dbus_entries, name))) {
1926 send_entry_removed_signal(de);
1927 dbus_entry_free(pa_hashmap_remove(u->dbus_entries, name));
1928 }
1929 #endif
1930
1931 key.data = (char*) name;
1932 key.size = strlen(name);
1933
1934 pa_database_unset(u->database, &key);
1935 }
1936
1937 trigger_save(u);
1938
1939 break;
1940
1941 case SUBCOMMAND_SUBSCRIBE: {
1942
1943 pa_bool_t enabled;
1944
1945 if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
1946 !pa_tagstruct_eof(t))
1947 goto fail;
1948
1949 if (enabled)
1950 pa_idxset_put(u->subscribed, c, NULL);
1951 else
1952 pa_idxset_remove_by_data(u->subscribed, c, NULL);
1953
1954 break;
1955 }
1956
1957 default:
1958 goto fail;
1959 }
1960
1961 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
1962 return 0;
1963
1964 fail:
1965
1966 if (reply)
1967 pa_tagstruct_free(reply);
1968
1969 return -1;
1970 }
1971
1972 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
1973 pa_assert(p);
1974 pa_assert(c);
1975 pa_assert(u);
1976
1977 pa_idxset_remove_by_data(u->subscribed, c, NULL);
1978 return PA_HOOK_OK;
1979 }
1980
1981 int pa__init(pa_module*m) {
1982 pa_modargs *ma = NULL;
1983 struct userdata *u;
1984 char *fname;
1985 pa_sink_input *si;
1986 pa_source_output *so;
1987 uint32_t idx;
1988 pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE, on_hotplug = TRUE, on_rescue = TRUE;
1989 #ifdef HAVE_DBUS
1990 pa_datum key;
1991 pa_bool_t done;
1992 #endif
1993
1994 pa_assert(m);
1995
1996 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1997 pa_log("Failed to parse module arguments");
1998 goto fail;
1999 }
2000
2001 if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 ||
2002 pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
2003 pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
2004 pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 ||
2005 pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) {
2006 pa_log("restore_device=, restore_volume=, restore_muted=, on_hotplug= and on_rescue= expect boolean arguments");
2007 goto fail;
2008 }
2009
2010 if (!restore_muted && !restore_volume && !restore_device)
2011 pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring device enabled!");
2012
2013 m->userdata = u = pa_xnew0(struct userdata, 1);
2014 u->core = m->core;
2015 u->module = m;
2016 u->restore_device = restore_device;
2017 u->restore_volume = restore_volume;
2018 u->restore_muted = restore_muted;
2019 u->on_hotplug = on_hotplug;
2020 u->on_rescue = on_rescue;
2021 u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
2022
2023 u->protocol = pa_native_protocol_get(m->core);
2024 pa_native_protocol_install_ext(u->protocol, m, extension_cb);
2025
2026 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);
2027
2028 u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u);
2029
2030 if (restore_device) {
2031 /* A little bit earlier than module-intended-roles ... */
2032 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);
2033 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);
2034 }
2035
2036 if (restore_device && on_hotplug) {
2037 /* A little bit earlier than module-intended-roles ... */
2038 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);
2039 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);
2040 }
2041
2042 if (restore_device && on_rescue) {
2043 /* A little bit earlier than module-intended-roles, module-rescue-streams, ... */
2044 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);
2045 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);
2046 }
2047
2048 if (restore_volume || restore_muted)
2049 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);
2050
2051 if (!(fname = pa_state_path("stream-volumes", TRUE)))
2052 goto fail;
2053
2054 if (!(u->database = pa_database_open(fname, TRUE))) {
2055 pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
2056 pa_xfree(fname);
2057 goto fail;
2058 }
2059
2060 pa_log_info("Successfully opened database file '%s'.", fname);
2061 pa_xfree(fname);
2062
2063 #ifdef HAVE_DBUS
2064 u->dbus_protocol = pa_dbus_protocol_get(u->core);
2065 u->dbus_entries = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
2066
2067 pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, OBJECT_PATH, &stream_restore_interface_info, u) >= 0);
2068 pa_assert_se(pa_dbus_protocol_register_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2069
2070 /* Create the initial dbus entries. */
2071 done = !pa_database_first(u->database, &key, NULL);
2072 while (!done) {
2073 pa_datum next_key;
2074 char *name;
2075 struct dbus_entry *de;
2076 struct entry *e;
2077
2078 done = !pa_database_next(u->database, &key, &next_key, NULL);
2079
2080 name = pa_xstrndup(key.data, key.size);
2081 pa_datum_free(&key);
2082
2083 /* Use read_entry() for checking that the entry is valid. */
2084 if ((e = read_entry(u, name))) {
2085 de = dbus_entry_new(u, name);
2086 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
2087 pa_xfree(e);
2088 }
2089
2090 pa_xfree(name);
2091
2092 key = next_key;
2093 }
2094 #endif
2095
2096 PA_IDXSET_FOREACH(si, m->core->sink_inputs, idx)
2097 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, si->index, u);
2098
2099 PA_IDXSET_FOREACH(so, m->core->source_outputs, idx)
2100 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, so->index, u);
2101
2102 pa_modargs_free(ma);
2103 return 0;
2104
2105 fail:
2106 pa__done(m);
2107
2108 if (ma)
2109 pa_modargs_free(ma);
2110
2111 return -1;
2112 }
2113
2114 #ifdef HAVE_DBUS
2115 static void free_dbus_entry_cb(void *p, void *userdata) {
2116 struct dbus_entry *de = p;
2117
2118 pa_assert(de);
2119
2120 dbus_entry_free(de);
2121 }
2122 #endif
2123
2124 void pa__done(pa_module*m) {
2125 struct userdata* u;
2126
2127 pa_assert(m);
2128
2129 if (!(u = m->userdata))
2130 return;
2131
2132 #ifdef HAVE_DBUS
2133 if (u->dbus_protocol) {
2134 pa_assert(u->dbus_entries);
2135
2136 pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2137 pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, OBJECT_PATH, stream_restore_interface_info.name) >= 0);
2138
2139 pa_hashmap_free(u->dbus_entries, free_dbus_entry_cb, NULL);
2140
2141 pa_dbus_protocol_unref(u->dbus_protocol);
2142 }
2143 #endif
2144
2145 if (u->subscription)
2146 pa_subscription_free(u->subscription);
2147
2148 if (u->sink_input_new_hook_slot)
2149 pa_hook_slot_free(u->sink_input_new_hook_slot);
2150 if (u->sink_input_fixate_hook_slot)
2151 pa_hook_slot_free(u->sink_input_fixate_hook_slot);
2152 if (u->source_output_new_hook_slot)
2153 pa_hook_slot_free(u->source_output_new_hook_slot);
2154
2155 if (u->sink_put_hook_slot)
2156 pa_hook_slot_free(u->sink_put_hook_slot);
2157 if (u->source_put_hook_slot)
2158 pa_hook_slot_free(u->source_put_hook_slot);
2159
2160 if (u->sink_unlink_hook_slot)
2161 pa_hook_slot_free(u->sink_unlink_hook_slot);
2162 if (u->source_unlink_hook_slot)
2163 pa_hook_slot_free(u->source_unlink_hook_slot);
2164
2165 if (u->connection_unlink_hook_slot)
2166 pa_hook_slot_free(u->connection_unlink_hook_slot);
2167
2168 if (u->save_time_event)
2169 u->core->mainloop->time_free(u->save_time_event);
2170
2171 if (u->database)
2172 pa_database_close(u->database);
2173
2174 if (u->protocol) {
2175 pa_native_protocol_remove_ext(u->protocol, m);
2176 pa_native_protocol_unref(u->protocol);
2177 }
2178
2179 if (u->subscribed)
2180 pa_idxset_free(u->subscribed, NULL, NULL);
2181
2182 pa_xfree(u);
2183 }