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