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