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