]> code.delx.au - pulseaudio/blob - src/modules/module-stream-restore.c
volume: Fix incorrect usage of PA_VOLUME_IS_VALID
[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 entry.channel_map = sink_input->channel_map;
1172 pa_sink_input_get_volume(sink_input, &entry.volume, FALSE);
1173 entry.volume_valid = TRUE;
1174
1175 volume_updated = !created_new_entry
1176 && (!old->volume_valid
1177 || !pa_channel_map_equal(&entry.channel_map, &old->channel_map)
1178 || !pa_cvolume_equal(&entry.volume, &old->volume));
1179 }
1180
1181 if (sink_input->save_muted) {
1182 entry.muted = pa_sink_input_get_mute(sink_input);
1183 entry.muted_valid = TRUE;
1184
1185 mute_updated = !created_new_entry && (!old->muted_valid || entry.muted != old->muted);
1186 }
1187
1188 if (sink_input->save_sink) {
1189 pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device));
1190 entry.device_valid = TRUE;
1191
1192 device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry.device, old->device));
1193 if (sink_input->sink->card) {
1194 pa_strlcpy(entry.card, sink_input->sink->card->name, sizeof(entry.card));
1195 entry.card_valid = TRUE;
1196 }
1197 }
1198
1199 } else {
1200 pa_source_output *source_output;
1201
1202 pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT);
1203
1204 if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx)))
1205 return;
1206
1207 if (!(name = get_name(source_output->proplist, "source-output")))
1208 return;
1209
1210 if ((old = read_entry(u, name))) {
1211 entry = *old;
1212 created_new_entry = FALSE;
1213 }
1214
1215 if (source_output->save_source) {
1216 pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device));
1217 entry.device_valid = source_output->save_source;
1218
1219 device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry.device, old->device));
1220
1221 if (source_output->source->card) {
1222 pa_strlcpy(entry.card, source_output->source->card->name, sizeof(entry.card));
1223 entry.card_valid = TRUE;
1224 }
1225 }
1226 }
1227
1228 if (old) {
1229
1230 if (entries_equal(old, &entry)) {
1231 pa_xfree(old);
1232 pa_xfree(name);
1233 return;
1234 }
1235
1236 pa_xfree(old);
1237 }
1238
1239 key.data = name;
1240 key.size = strlen(name);
1241
1242 data.data = &entry;
1243 data.size = sizeof(entry);
1244
1245 pa_log_info("Storing volume/mute/device for stream %s.", name);
1246
1247 pa_database_set(u->database, &key, &data, TRUE);
1248
1249 #ifdef HAVE_DBUS
1250 if (created_new_entry) {
1251 de = dbus_entry_new(u, name);
1252 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
1253 send_new_entry_signal(de);
1254 } else {
1255 pa_assert_se(de = pa_hashmap_get(u->dbus_entries, name));
1256
1257 if (device_updated)
1258 send_device_updated_signal(de, &entry);
1259 if (volume_updated)
1260 send_volume_updated_signal(de, &entry);
1261 if (mute_updated)
1262 send_mute_updated_signal(de, &entry);
1263 }
1264 #endif
1265
1266 pa_xfree(name);
1267
1268 trigger_save(u);
1269 }
1270
1271 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1272 char *name;
1273 struct entry *e;
1274
1275 pa_assert(c);
1276 pa_assert(new_data);
1277 pa_assert(u);
1278 pa_assert(u->restore_device);
1279
1280 if (!(name = get_name(new_data->proplist, "sink-input")))
1281 return PA_HOOK_OK;
1282
1283 if (new_data->sink)
1284 pa_log_debug("Not restoring device for stream %s, because already set to '%s'.", name, new_data->sink->name);
1285 else if ((e = read_entry(u, name))) {
1286 pa_sink *s = NULL;
1287
1288 if (e->device_valid)
1289 s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK);
1290
1291 if (!s && e->card_valid) {
1292 pa_card *card;
1293
1294 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1295 s = pa_idxset_first(card->sinks, NULL);
1296 }
1297
1298 /* It might happen that a stream and a sink are set up at the
1299 same time, in which case we want to make sure we don't
1300 interfere with that */
1301 if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s))) {
1302 pa_log_info("Restoring device for stream %s.", name);
1303 new_data->sink = s;
1304 new_data->save_sink = TRUE;
1305 }
1306
1307 pa_xfree(e);
1308 }
1309
1310 pa_xfree(name);
1311
1312 return PA_HOOK_OK;
1313 }
1314
1315 static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
1316 char *name;
1317 struct entry *e;
1318
1319 pa_assert(c);
1320 pa_assert(new_data);
1321 pa_assert(u);
1322 pa_assert(u->restore_volume || u->restore_muted);
1323
1324 if (!(name = get_name(new_data->proplist, "sink-input")))
1325 return PA_HOOK_OK;
1326
1327 if ((e = read_entry(u, name))) {
1328
1329 if (u->restore_volume && e->volume_valid) {
1330
1331 if (!new_data->volume_is_set) {
1332 pa_cvolume v;
1333
1334 pa_log_info("Restoring volume for sink input %s.", name);
1335
1336 v = e->volume;
1337 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
1338 pa_sink_input_new_data_set_volume(new_data, &v);
1339
1340 new_data->volume_is_absolute = FALSE;
1341 new_data->save_volume = TRUE;
1342 } else
1343 pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
1344 }
1345
1346 if (u->restore_muted && e->muted_valid) {
1347
1348 if (!new_data->muted_is_set) {
1349 pa_log_info("Restoring mute state for sink input %s.", name);
1350 pa_sink_input_new_data_set_muted(new_data, e->muted);
1351 new_data->save_muted = TRUE;
1352 } else
1353 pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
1354 }
1355
1356 pa_xfree(e);
1357 }
1358
1359 pa_xfree(name);
1360
1361 return PA_HOOK_OK;
1362 }
1363
1364 static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
1365 char *name;
1366 struct entry *e;
1367
1368 pa_assert(c);
1369 pa_assert(new_data);
1370 pa_assert(u);
1371 pa_assert(u->restore_device);
1372
1373 if (new_data->direct_on_input)
1374 return PA_HOOK_OK;
1375
1376 if (!(name = get_name(new_data->proplist, "source-output")))
1377 return PA_HOOK_OK;
1378
1379 if (new_data->source)
1380 pa_log_debug("Not restoring device for stream %s, because already set", name);
1381 else if ((e = read_entry(u, name))) {
1382 pa_source *s = NULL;
1383
1384 if (e->device_valid)
1385 s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE);
1386
1387 if (!s && e->card_valid) {
1388 pa_card *card;
1389
1390 if ((card = pa_namereg_get(c, e->card, PA_NAMEREG_CARD)))
1391 s = pa_idxset_first(card->sources, NULL);
1392 }
1393
1394 /* It might happen that a stream and a sink are set up at the
1395 same time, in which case we want to make sure we don't
1396 interfere with that */
1397 if (s && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) {
1398 pa_log_info("Restoring device for stream %s.", name);
1399 new_data->source = s;
1400 new_data->save_source = TRUE;
1401 }
1402
1403 pa_xfree(e);
1404 }
1405
1406 pa_xfree(name);
1407
1408 return PA_HOOK_OK;
1409 }
1410
1411 static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
1412 pa_sink_input *si;
1413 uint32_t idx;
1414
1415 pa_assert(c);
1416 pa_assert(sink);
1417 pa_assert(u);
1418 pa_assert(u->on_hotplug && u->restore_device);
1419
1420 PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
1421 char *name;
1422 struct entry *e;
1423
1424 if (si->sink == sink)
1425 continue;
1426
1427 if (si->save_sink)
1428 continue;
1429
1430 /* Skip this if it is already in the process of being moved
1431 * anyway */
1432 if (!si->sink)
1433 continue;
1434
1435 /* It might happen that a stream and a sink are set up at the
1436 same time, in which case we want to make sure we don't
1437 interfere with that */
1438 if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si)))
1439 continue;
1440
1441 if (!(name = get_name(si->proplist, "sink-input")))
1442 continue;
1443
1444 if ((e = read_entry(u, name))) {
1445 if (e->device_valid && pa_streq(e->device, sink->name))
1446 pa_sink_input_move_to(si, sink, TRUE);
1447
1448 pa_xfree(e);
1449 }
1450
1451 pa_xfree(name);
1452 }
1453
1454 return PA_HOOK_OK;
1455 }
1456
1457 static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
1458 pa_source_output *so;
1459 uint32_t idx;
1460
1461 pa_assert(c);
1462 pa_assert(source);
1463 pa_assert(u);
1464 pa_assert(u->on_hotplug && u->restore_device);
1465
1466 PA_IDXSET_FOREACH(so, c->source_outputs, idx) {
1467 char *name;
1468 struct entry *e;
1469
1470 if (so->source == source)
1471 continue;
1472
1473 if (so->save_source)
1474 continue;
1475
1476 if (so->direct_on_input)
1477 continue;
1478
1479 /* Skip this if it is already in the process of being moved anyway */
1480 if (!so->source)
1481 continue;
1482
1483 /* It might happen that a stream and a source are set up at the
1484 same time, in which case we want to make sure we don't
1485 interfere with that */
1486 if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(so)))
1487 continue;
1488
1489 if (!(name = get_name(so->proplist, "source-input")))
1490 continue;
1491
1492 if ((e = read_entry(u, name))) {
1493 if (e->device_valid && pa_streq(e->device, source->name))
1494 pa_source_output_move_to(so, source, TRUE);
1495
1496 pa_xfree(e);
1497 }
1498
1499 pa_xfree(name);
1500 }
1501
1502 return PA_HOOK_OK;
1503 }
1504
1505 static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
1506 pa_sink_input *si;
1507 uint32_t idx;
1508
1509 pa_assert(c);
1510 pa_assert(sink);
1511 pa_assert(u);
1512 pa_assert(u->on_rescue && u->restore_device);
1513
1514 /* There's no point in doing anything if the core is shut down anyway */
1515 if (c->state == PA_CORE_SHUTDOWN)
1516 return PA_HOOK_OK;
1517
1518 PA_IDXSET_FOREACH(si, sink->inputs, idx) {
1519 char *name;
1520 struct entry *e;
1521
1522 if (!si->sink)
1523 continue;
1524
1525 if (!(name = get_name(si->proplist, "sink-input")))
1526 continue;
1527
1528 if ((e = read_entry(u, name))) {
1529
1530 if (e->device_valid) {
1531 pa_sink *d;
1532
1533 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) &&
1534 d != sink &&
1535 PA_SINK_IS_LINKED(pa_sink_get_state(d)))
1536 pa_sink_input_move_to(si, d, TRUE);
1537 }
1538
1539 pa_xfree(e);
1540 }
1541
1542 pa_xfree(name);
1543 }
1544
1545 return PA_HOOK_OK;
1546 }
1547
1548 static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
1549 pa_source_output *so;
1550 uint32_t idx;
1551
1552 pa_assert(c);
1553 pa_assert(source);
1554 pa_assert(u);
1555 pa_assert(u->on_rescue && u->restore_device);
1556
1557 /* There's no point in doing anything if the core is shut down anyway */
1558 if (c->state == PA_CORE_SHUTDOWN)
1559 return PA_HOOK_OK;
1560
1561 PA_IDXSET_FOREACH(so, source->outputs, idx) {
1562 char *name;
1563 struct entry *e;
1564
1565 if (so->direct_on_input)
1566 continue;
1567
1568 if (!so->source)
1569 continue;
1570
1571 if (!(name = get_name(so->proplist, "source-output")))
1572 continue;
1573
1574 if ((e = read_entry(u, name))) {
1575
1576 if (e->device_valid) {
1577 pa_source *d;
1578
1579 if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE)) &&
1580 d != source &&
1581 PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
1582 pa_source_output_move_to(so, d, TRUE);
1583 }
1584
1585 pa_xfree(e);
1586 }
1587
1588 pa_xfree(name);
1589 }
1590
1591 return PA_HOOK_OK;
1592 }
1593
1594 #define EXT_VERSION 1
1595
1596 static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
1597 pa_sink_input *si;
1598 pa_source_output *so;
1599 uint32_t idx;
1600
1601 pa_assert(u);
1602 pa_assert(name);
1603 pa_assert(e);
1604
1605 PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
1606 char *n;
1607 pa_sink *s;
1608
1609 if (!(n = get_name(si->proplist, "sink-input")))
1610 continue;
1611
1612 if (!pa_streq(name, n)) {
1613 pa_xfree(n);
1614 continue;
1615 }
1616 pa_xfree(n);
1617
1618 if (u->restore_volume && e->volume_valid) {
1619 pa_cvolume v;
1620
1621 v = e->volume;
1622 pa_log_info("Restoring volume for sink input %s.", name);
1623 pa_cvolume_remap(&v, &e->channel_map, &si->channel_map);
1624 pa_sink_input_set_volume(si, &v, TRUE, FALSE);
1625 }
1626
1627 if (u->restore_muted && e->muted_valid) {
1628 pa_log_info("Restoring mute state for sink input %s.", name);
1629 pa_sink_input_set_mute(si, e->muted, TRUE);
1630 }
1631
1632 if (u->restore_device) {
1633 if (!e->device_valid) {
1634 if (si->save_sink) {
1635 pa_log_info("Ensuring device is not saved for stream %s.", name);
1636 /* If the device is not valid we should make sure the
1637 save flag is cleared as the user may have specifically
1638 removed the sink element from the rule. */
1639 si->save_sink = FALSE;
1640 /* This is cheating a bit. The sink input itself has not changed
1641 but the rules governing it's routing have, so we fire this event
1642 such that other routing modules (e.g. module-device-manager)
1643 will pick up the change and reapply their routing */
1644 pa_subscription_post(si->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, si->index);
1645 }
1646 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) {
1647 pa_log_info("Restoring device for stream %s.", name);
1648 pa_sink_input_move_to(si, s, TRUE);
1649 }
1650 }
1651 }
1652
1653 PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
1654 char *n;
1655 pa_source *s;
1656
1657 if (!(n = get_name(so->proplist, "source-output")))
1658 continue;
1659
1660 if (!pa_streq(name, n)) {
1661 pa_xfree(n);
1662 continue;
1663 }
1664 pa_xfree(n);
1665
1666 if (u->restore_device) {
1667 if (!e->device_valid) {
1668 if (so->save_source) {
1669 pa_log_info("Ensuring device is not saved for stream %s.", name);
1670 /* If the device is not valid we should make sure the
1671 save flag is cleared as the user may have specifically
1672 removed the source element from the rule. */
1673 so->save_source = FALSE;
1674 /* This is cheating a bit. The source output itself has not changed
1675 but the rules governing it's routing have, so we fire this event
1676 such that other routing modules (e.g. module-device-manager)
1677 will pick up the change and reapply their routing */
1678 pa_subscription_post(so->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, so->index);
1679 }
1680 } else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
1681 pa_log_info("Restoring device for stream %s.", name);
1682 pa_source_output_move_to(so, s, TRUE);
1683 }
1684 }
1685 }
1686 }
1687
1688 #if 0
1689 static void dump_database(struct userdata *u) {
1690 pa_datum key;
1691 pa_bool_t done;
1692
1693 done = !pa_database_first(u->database, &key, NULL);
1694
1695 while (!done) {
1696 pa_datum next_key;
1697 struct entry *e;
1698 char *name;
1699
1700 done = !pa_database_next(u->database, &key, &next_key, NULL);
1701
1702 name = pa_xstrndup(key.data, key.size);
1703 pa_datum_free(&key);
1704
1705 if ((e = read_entry(u, name))) {
1706 char t[256];
1707 pa_log("name=%s", name);
1708 pa_log("device=%s %s", e->device, pa_yes_no(e->device_valid));
1709 pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map));
1710 pa_log("volume=%s %s", pa_cvolume_snprint(t, sizeof(t), &e->volume), pa_yes_no(e->volume_valid));
1711 pa_log("mute=%s %s", pa_yes_no(e->muted), pa_yes_no(e->volume_valid));
1712 pa_xfree(e);
1713 }
1714
1715 pa_xfree(name);
1716
1717 key = next_key;
1718 }
1719 }
1720 #endif
1721
1722 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
1723 struct userdata *u;
1724 uint32_t command;
1725 pa_tagstruct *reply = NULL;
1726
1727 pa_assert(p);
1728 pa_assert(m);
1729 pa_assert(c);
1730 pa_assert(t);
1731
1732 u = m->userdata;
1733
1734 if (pa_tagstruct_getu32(t, &command) < 0)
1735 goto fail;
1736
1737 reply = pa_tagstruct_new(NULL, 0);
1738 pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
1739 pa_tagstruct_putu32(reply, tag);
1740
1741 switch (command) {
1742 case SUBCOMMAND_TEST: {
1743 if (!pa_tagstruct_eof(t))
1744 goto fail;
1745
1746 pa_tagstruct_putu32(reply, EXT_VERSION);
1747 break;
1748 }
1749
1750 case SUBCOMMAND_READ: {
1751 pa_datum key;
1752 pa_bool_t done;
1753
1754 if (!pa_tagstruct_eof(t))
1755 goto fail;
1756
1757 done = !pa_database_first(u->database, &key, NULL);
1758
1759 while (!done) {
1760 pa_datum next_key;
1761 struct entry *e;
1762 char *name;
1763
1764 done = !pa_database_next(u->database, &key, &next_key, NULL);
1765
1766 name = pa_xstrndup(key.data, key.size);
1767 pa_datum_free(&key);
1768
1769 if ((e = read_entry(u, name))) {
1770 pa_cvolume r;
1771 pa_channel_map cm;
1772
1773 pa_tagstruct_puts(reply, name);
1774 pa_tagstruct_put_channel_map(reply, e->volume_valid ? &e->channel_map : pa_channel_map_init(&cm));
1775 pa_tagstruct_put_cvolume(reply, e->volume_valid ? &e->volume : pa_cvolume_init(&r));
1776 pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
1777 pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
1778
1779 pa_xfree(e);
1780 }
1781
1782 pa_xfree(name);
1783
1784 key = next_key;
1785 }
1786
1787 break;
1788 }
1789
1790 case SUBCOMMAND_WRITE: {
1791 uint32_t mode;
1792 pa_bool_t apply_immediately = FALSE;
1793
1794 if (pa_tagstruct_getu32(t, &mode) < 0 ||
1795 pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
1796 goto fail;
1797
1798 if (mode != PA_UPDATE_MERGE &&
1799 mode != PA_UPDATE_REPLACE &&
1800 mode != PA_UPDATE_SET)
1801 goto fail;
1802
1803 if (mode == PA_UPDATE_SET) {
1804 #ifdef HAVE_DBUS
1805 struct dbus_entry *de;
1806 void *state = NULL;
1807
1808 PA_HASHMAP_FOREACH(de, u->dbus_entries, state) {
1809 send_entry_removed_signal(de);
1810 dbus_entry_free(pa_hashmap_remove(u->dbus_entries, de->entry_name));
1811 }
1812 #endif
1813 pa_database_clear(u->database);
1814 }
1815
1816 while (!pa_tagstruct_eof(t)) {
1817 const char *name, *device;
1818 pa_bool_t muted;
1819 struct entry entry;
1820 pa_datum key, data;
1821 #ifdef HAVE_DBUS
1822 struct entry *old;
1823 #endif
1824
1825 pa_zero(entry);
1826 entry.version = ENTRY_VERSION;
1827
1828 if (pa_tagstruct_gets(t, &name) < 0 ||
1829 pa_tagstruct_get_channel_map(t, &entry.channel_map) ||
1830 pa_tagstruct_get_cvolume(t, &entry.volume) < 0 ||
1831 pa_tagstruct_gets(t, &device) < 0 ||
1832 pa_tagstruct_get_boolean(t, &muted) < 0)
1833 goto fail;
1834
1835 if (!name || !*name)
1836 goto fail;
1837
1838 entry.volume_valid = entry.volume.channels > 0;
1839
1840 if (entry.volume_valid)
1841 if (!pa_cvolume_compatible_with_channel_map(&entry.volume, &entry.channel_map))
1842 goto fail;
1843
1844 entry.muted = muted;
1845 entry.muted_valid = TRUE;
1846
1847 if (device)
1848 pa_strlcpy(entry.device, device, sizeof(entry.device));
1849 entry.device_valid = !!entry.device[0];
1850
1851 if (entry.device_valid &&
1852 !pa_namereg_is_valid_name(entry.device))
1853 goto fail;
1854
1855 #ifdef HAVE_DBUS
1856 old = read_entry(u, name);
1857 #endif
1858
1859 key.data = (char*) name;
1860 key.size = strlen(name);
1861
1862 data.data = &entry;
1863 data.size = sizeof(entry);
1864
1865 pa_log_debug("Client %s changes entry %s.",
1866 pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)),
1867 name);
1868
1869 if (pa_database_set(u->database, &key, &data, mode == PA_UPDATE_REPLACE) == 0) {
1870 #ifdef HAVE_DBUS
1871 struct dbus_entry *de;
1872
1873 if (old) {
1874 pa_assert_se((de = pa_hashmap_get(u->dbus_entries, name)));
1875
1876 if ((old->device_valid != entry.device_valid)
1877 || (entry.device_valid && !pa_streq(entry.device, old->device)))
1878 send_device_updated_signal(de, &entry);
1879
1880 if ((old->volume_valid != entry.volume_valid)
1881 || (entry.volume_valid && (!pa_cvolume_equal(&entry.volume, &old->volume)
1882 || !pa_channel_map_equal(&entry.channel_map, &old->channel_map))))
1883 send_volume_updated_signal(de, &entry);
1884
1885 if (!old->muted_valid || (entry.muted != old->muted))
1886 send_mute_updated_signal(de, &entry);
1887
1888 } else {
1889 de = dbus_entry_new(u, name);
1890 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
1891 send_new_entry_signal(de);
1892 }
1893 #endif
1894
1895 if (apply_immediately)
1896 apply_entry(u, name, &entry);
1897 }
1898
1899 #ifdef HAVE_DBUS
1900 if (old)
1901 pa_xfree(old);
1902 #endif
1903 }
1904
1905 trigger_save(u);
1906
1907 break;
1908 }
1909
1910 case SUBCOMMAND_DELETE:
1911
1912 while (!pa_tagstruct_eof(t)) {
1913 const char *name;
1914 pa_datum key;
1915 #ifdef HAVE_DBUS
1916 struct dbus_entry *de;
1917 #endif
1918
1919 if (pa_tagstruct_gets(t, &name) < 0)
1920 goto fail;
1921
1922 #ifdef HAVE_DBUS
1923 if ((de = pa_hashmap_get(u->dbus_entries, name))) {
1924 send_entry_removed_signal(de);
1925 dbus_entry_free(pa_hashmap_remove(u->dbus_entries, name));
1926 }
1927 #endif
1928
1929 key.data = (char*) name;
1930 key.size = strlen(name);
1931
1932 pa_database_unset(u->database, &key);
1933 }
1934
1935 trigger_save(u);
1936
1937 break;
1938
1939 case SUBCOMMAND_SUBSCRIBE: {
1940
1941 pa_bool_t enabled;
1942
1943 if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
1944 !pa_tagstruct_eof(t))
1945 goto fail;
1946
1947 if (enabled)
1948 pa_idxset_put(u->subscribed, c, NULL);
1949 else
1950 pa_idxset_remove_by_data(u->subscribed, c, NULL);
1951
1952 break;
1953 }
1954
1955 default:
1956 goto fail;
1957 }
1958
1959 pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
1960 return 0;
1961
1962 fail:
1963
1964 if (reply)
1965 pa_tagstruct_free(reply);
1966
1967 return -1;
1968 }
1969
1970 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
1971 pa_assert(p);
1972 pa_assert(c);
1973 pa_assert(u);
1974
1975 pa_idxset_remove_by_data(u->subscribed, c, NULL);
1976 return PA_HOOK_OK;
1977 }
1978
1979 int pa__init(pa_module*m) {
1980 pa_modargs *ma = NULL;
1981 struct userdata *u;
1982 char *fname;
1983 pa_sink_input *si;
1984 pa_source_output *so;
1985 uint32_t idx;
1986 pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE, on_hotplug = TRUE, on_rescue = TRUE;
1987 #ifdef HAVE_DBUS
1988 pa_datum key;
1989 pa_bool_t done;
1990 #endif
1991
1992 pa_assert(m);
1993
1994 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1995 pa_log("Failed to parse module arguments");
1996 goto fail;
1997 }
1998
1999 if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 ||
2000 pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
2001 pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
2002 pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 ||
2003 pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) {
2004 pa_log("restore_device=, restore_volume=, restore_muted=, on_hotplug= and on_rescue= expect boolean arguments");
2005 goto fail;
2006 }
2007
2008 if (!restore_muted && !restore_volume && !restore_device)
2009 pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring device enabled!");
2010
2011 m->userdata = u = pa_xnew0(struct userdata, 1);
2012 u->core = m->core;
2013 u->module = m;
2014 u->restore_device = restore_device;
2015 u->restore_volume = restore_volume;
2016 u->restore_muted = restore_muted;
2017 u->on_hotplug = on_hotplug;
2018 u->on_rescue = on_rescue;
2019 u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
2020
2021 u->protocol = pa_native_protocol_get(m->core);
2022 pa_native_protocol_install_ext(u->protocol, m, extension_cb);
2023
2024 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);
2025
2026 u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u);
2027
2028 if (restore_device) {
2029 /* A little bit earlier than module-intended-roles ... */
2030 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);
2031 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);
2032 }
2033
2034 if (restore_device && on_hotplug) {
2035 /* A little bit earlier than module-intended-roles ... */
2036 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);
2037 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);
2038 }
2039
2040 if (restore_device && on_rescue) {
2041 /* A little bit earlier than module-intended-roles, module-rescue-streams, ... */
2042 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);
2043 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);
2044 }
2045
2046 if (restore_volume || restore_muted)
2047 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);
2048
2049 if (!(fname = pa_state_path("stream-volumes", TRUE)))
2050 goto fail;
2051
2052 if (!(u->database = pa_database_open(fname, TRUE))) {
2053 pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
2054 pa_xfree(fname);
2055 goto fail;
2056 }
2057
2058 pa_log_info("Sucessfully opened database file '%s'.", fname);
2059 pa_xfree(fname);
2060
2061 #ifdef HAVE_DBUS
2062 u->dbus_protocol = pa_dbus_protocol_get(u->core);
2063 u->dbus_entries = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
2064
2065 pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, OBJECT_PATH, &stream_restore_interface_info, u) >= 0);
2066 pa_assert_se(pa_dbus_protocol_register_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2067
2068 /* Create the initial dbus entries. */
2069 done = !pa_database_first(u->database, &key, NULL);
2070 while (!done) {
2071 pa_datum next_key;
2072 char *name;
2073 struct dbus_entry *de;
2074 struct entry *e;
2075
2076 done = !pa_database_next(u->database, &key, &next_key, NULL);
2077
2078 name = pa_xstrndup(key.data, key.size);
2079 pa_datum_free(&key);
2080
2081 /* Use read_entry() for checking that the entry is valid. */
2082 if ((e = read_entry(u, name))) {
2083 de = dbus_entry_new(u, name);
2084 pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
2085 pa_xfree(e);
2086 }
2087
2088 pa_xfree(name);
2089
2090 key = next_key;
2091 }
2092 #endif
2093
2094 PA_IDXSET_FOREACH(si, m->core->sink_inputs, idx)
2095 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, si->index, u);
2096
2097 PA_IDXSET_FOREACH(so, m->core->source_outputs, idx)
2098 subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, so->index, u);
2099
2100 pa_modargs_free(ma);
2101 return 0;
2102
2103 fail:
2104 pa__done(m);
2105
2106 if (ma)
2107 pa_modargs_free(ma);
2108
2109 return -1;
2110 }
2111
2112 #ifdef HAVE_DBUS
2113 static void free_dbus_entry_cb(void *p, void *userdata) {
2114 struct dbus_entry *de = p;
2115
2116 pa_assert(de);
2117
2118 dbus_entry_free(de);
2119 }
2120 #endif
2121
2122 void pa__done(pa_module*m) {
2123 struct userdata* u;
2124
2125 pa_assert(m);
2126
2127 if (!(u = m->userdata))
2128 return;
2129
2130 #ifdef HAVE_DBUS
2131 if (u->dbus_protocol) {
2132 pa_assert(u->dbus_entries);
2133
2134 pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
2135 pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, OBJECT_PATH, stream_restore_interface_info.name) >= 0);
2136
2137 pa_hashmap_free(u->dbus_entries, free_dbus_entry_cb, NULL);
2138
2139 pa_dbus_protocol_unref(u->dbus_protocol);
2140 }
2141 #endif
2142
2143 if (u->subscription)
2144 pa_subscription_free(u->subscription);
2145
2146 if (u->sink_input_new_hook_slot)
2147 pa_hook_slot_free(u->sink_input_new_hook_slot);
2148 if (u->sink_input_fixate_hook_slot)
2149 pa_hook_slot_free(u->sink_input_fixate_hook_slot);
2150 if (u->source_output_new_hook_slot)
2151 pa_hook_slot_free(u->source_output_new_hook_slot);
2152
2153 if (u->sink_put_hook_slot)
2154 pa_hook_slot_free(u->sink_put_hook_slot);
2155 if (u->source_put_hook_slot)
2156 pa_hook_slot_free(u->source_put_hook_slot);
2157
2158 if (u->sink_unlink_hook_slot)
2159 pa_hook_slot_free(u->sink_unlink_hook_slot);
2160 if (u->source_unlink_hook_slot)
2161 pa_hook_slot_free(u->source_unlink_hook_slot);
2162
2163 if (u->connection_unlink_hook_slot)
2164 pa_hook_slot_free(u->connection_unlink_hook_slot);
2165
2166 if (u->save_time_event)
2167 u->core->mainloop->time_free(u->save_time_event);
2168
2169 if (u->database)
2170 pa_database_close(u->database);
2171
2172 if (u->protocol) {
2173 pa_native_protocol_remove_ext(u->protocol, m);
2174 pa_native_protocol_unref(u->protocol);
2175 }
2176
2177 if (u->subscribed)
2178 pa_idxset_free(u->subscribed, NULL, NULL);
2179
2180 pa_xfree(u);
2181 }