hashmap: Add pa_hashmap_remove_all()
[platform/upstream/pulseaudio.git] / src / modules / module-device-restore.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2006-2008 Lennart Poettering
5   Copyright 2011 Colin Guthrie
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
34 #include <pulse/gccmacro.h>
35 #include <pulse/xmalloc.h>
36 #include <pulse/volume.h>
37 #include <pulse/timeval.h>
38 #include <pulse/rtclock.h>
39 #include <pulse/format.h>
40 #include <pulse/internal.h>
41
42 #include <pulsecore/core-error.h>
43 #include <pulsecore/module.h>
44 #include <pulsecore/core-util.h>
45 #include <pulsecore/modargs.h>
46 #include <pulsecore/log.h>
47 #include <pulsecore/core-subscribe.h>
48 #include <pulsecore/sink.h>
49 #include <pulsecore/source.h>
50 #include <pulsecore/namereg.h>
51 #include <pulsecore/protocol-native.h>
52 #include <pulsecore/pstream.h>
53 #include <pulsecore/pstream-util.h>
54 #include <pulsecore/database.h>
55 #include <pulsecore/tagstruct.h>
56
57 #include "module-device-restore-symdef.h"
58
59 PA_MODULE_AUTHOR("Lennart Poettering");
60 PA_MODULE_DESCRIPTION("Automatically restore the volume/mute state of devices");
61 PA_MODULE_VERSION(PACKAGE_VERSION);
62 PA_MODULE_LOAD_ONCE(TRUE);
63 PA_MODULE_USAGE(
64         "restore_port=<Save/restore port?> "
65         "restore_volume=<Save/restore volumes?> "
66         "restore_muted=<Save/restore muted states?> "
67         "restore_formats=<Save/restore saved formats?>");
68
69 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
70
71 static const char* const valid_modargs[] = {
72     "restore_volume",
73     "restore_muted",
74     "restore_port",
75     "restore_formats",
76     NULL
77 };
78
79 struct userdata {
80     pa_core *core;
81     pa_module *module;
82     pa_subscription *subscription;
83     pa_hook_slot
84         *sink_new_hook_slot,
85         *sink_fixate_hook_slot,
86         *sink_port_hook_slot,
87         *sink_put_hook_slot,
88         *source_new_hook_slot,
89         *source_fixate_hook_slot,
90         *source_port_hook_slot,
91         *connection_unlink_hook_slot;
92     pa_time_event *save_time_event;
93     pa_database *database;
94
95     pa_native_protocol *protocol;
96     pa_idxset *subscribed;
97
98     pa_bool_t restore_volume:1;
99     pa_bool_t restore_muted:1;
100     pa_bool_t restore_port:1;
101     pa_bool_t restore_formats:1;
102 };
103
104 /* Protocol extension commands */
105 enum {
106     SUBCOMMAND_TEST,
107     SUBCOMMAND_SUBSCRIBE,
108     SUBCOMMAND_EVENT,
109     SUBCOMMAND_READ_FORMATS_ALL,
110     SUBCOMMAND_READ_FORMATS,
111     SUBCOMMAND_SAVE_FORMATS
112 };
113
114
115 #define ENTRY_VERSION 1
116
117 struct entry {
118     uint8_t version;
119     pa_bool_t port_valid;
120     char *port;
121 };
122
123 #define PERPORTENTRY_VERSION 1
124
125 struct perportentry {
126     uint8_t version;
127     pa_bool_t muted_valid, volume_valid;
128     pa_bool_t muted;
129     pa_channel_map channel_map;
130     pa_cvolume volume;
131     pa_idxset *formats;
132 };
133
134 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
135     struct userdata *u = userdata;
136
137     pa_assert(a);
138     pa_assert(e);
139     pa_assert(u);
140
141     pa_assert(e == u->save_time_event);
142     u->core->mainloop->time_free(u->save_time_event);
143     u->save_time_event = NULL;
144
145     pa_database_sync(u->database);
146     pa_log_info("Synced.");
147 }
148
149 static void trigger_save(struct userdata *u, pa_device_type_t type, uint32_t sink_idx) {
150     pa_native_connection *c;
151     uint32_t idx;
152
153     if (sink_idx != PA_INVALID_INDEX) {
154         PA_IDXSET_FOREACH(c, u->subscribed, idx) {
155             pa_tagstruct *t;
156
157             t = pa_tagstruct_new(NULL, 0);
158             pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
159             pa_tagstruct_putu32(t, 0);
160             pa_tagstruct_putu32(t, u->module->index);
161             pa_tagstruct_puts(t, u->module->name);
162             pa_tagstruct_putu32(t, SUBCOMMAND_EVENT);
163             pa_tagstruct_putu32(t, type);
164             pa_tagstruct_putu32(t, sink_idx);
165
166             pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t);
167         }
168     }
169
170     if (u->save_time_event)
171         return;
172
173     u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
174 }
175
176
177 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
178 /* Some forward declarations */
179 static pa_bool_t legacy_entry_read(struct userdata *u, pa_datum *data, struct entry **entry, struct perportentry **perportentry);
180 static struct perportentry* perportentry_read(struct userdata *u, const char *basekeyname, const char *port);
181 static pa_bool_t perportentry_write(struct userdata *u, const char *basekeyname, const char *port, const struct perportentry *e);
182 static void perportentry_free(struct perportentry* e);
183 #endif
184
185 static struct entry* entry_new(void) {
186     struct entry *r = pa_xnew0(struct entry, 1);
187     r->version = ENTRY_VERSION;
188     return r;
189 }
190
191 static void entry_free(struct entry* e) {
192     pa_assert(e);
193
194     pa_xfree(e->port);
195     pa_xfree(e);
196 }
197
198 static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e) {
199     pa_tagstruct *t;
200     pa_datum key, data;
201     pa_bool_t r;
202
203     pa_assert(u);
204     pa_assert(name);
205     pa_assert(e);
206
207     t = pa_tagstruct_new(NULL, 0);
208     pa_tagstruct_putu8(t, e->version);
209     pa_tagstruct_put_boolean(t, e->port_valid);
210     pa_tagstruct_puts(t, e->port);
211
212     key.data = (char *) name;
213     key.size = strlen(name);
214
215     data.data = (void*)pa_tagstruct_data(t, &data.size);
216
217     r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
218
219     pa_tagstruct_free(t);
220
221     return r;
222 }
223
224 static struct entry* entry_read(struct userdata *u, const char *name) {
225     pa_datum key, data;
226     struct entry *e = NULL;
227     pa_tagstruct *t = NULL;
228     const char* port;
229
230     pa_assert(u);
231     pa_assert(name);
232
233     key.data = (char*) name;
234     key.size = strlen(name);
235
236     pa_zero(data);
237
238     if (!pa_database_get(u->database, &key, &data))
239         goto fail;
240
241     t = pa_tagstruct_new(data.data, data.size);
242     e = entry_new();
243
244     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
245         e->version > ENTRY_VERSION ||
246         pa_tagstruct_get_boolean(t, &e->port_valid) < 0 ||
247         pa_tagstruct_gets(t, &port) < 0) {
248
249         goto fail;
250     }
251
252     if (!pa_tagstruct_eof(t))
253         goto fail;
254
255     e->port = pa_xstrdup(port);
256
257     pa_tagstruct_free(t);
258     pa_datum_free(&data);
259
260     return e;
261
262 fail:
263
264     pa_log_debug("Database contains invalid data for key: %s (probably pre-v1.0 data)", name);
265
266     if (e)
267         entry_free(e);
268     if (t)
269         pa_tagstruct_free(t);
270
271 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
272 {
273     struct perportentry *ppe;
274     pa_log_debug("Attempting to load legacy (pre-v1.0) data for key: %s", name);
275     if (legacy_entry_read(u, &data, &e, &ppe)) {
276         pa_bool_t written = FALSE;
277
278         pa_log_debug("Success. Saving new format for key: %s", name);
279         written = entry_write(u, name, e);
280
281         /* Now convert the legacy entry into per-port entries */
282         if (0 == strncmp("sink:", name, 5)) {
283             pa_sink *sink;
284
285             if ((sink = pa_namereg_get(u->core, name+5, PA_NAMEREG_SINK))) {
286                 /* Write a "null" port entry. The read code will automatically try this
287                  * if it cannot find a specific port-named entry. */
288                 written = perportentry_write(u, name, NULL, ppe) || written;
289             }
290         } else if (0 == strncmp("source:", name, 7)) {
291             pa_source *source;
292
293             if ((source = pa_namereg_get(u->core, name+7, PA_NAMEREG_SOURCE))) {
294                 /* Write a "null" port entry. The read code will automatically try this
295                  * if it cannot find a specific port-named entry. */
296                 written = perportentry_write(u, name, NULL, ppe) || written;
297             }
298         }
299         perportentry_free(ppe);
300
301         if (written)
302             /* NB The device type doesn't matter when we pass in an invalid index. */
303             trigger_save(u, PA_DEVICE_TYPE_SINK, PA_INVALID_INDEX);
304
305         pa_datum_free(&data);
306         return e;
307     }
308     pa_log_debug("Unable to load legacy (pre-v1.0) data for key: %s. Ignoring.", name);
309 }
310 #endif
311
312     pa_datum_free(&data);
313     return NULL;
314 }
315
316 static struct entry* entry_copy(const struct entry *e) {
317     struct entry* r;
318
319     pa_assert(e);
320     r = entry_new();
321     r->version = e->version;
322     r->port_valid = e->port_valid;
323     r->port = pa_xstrdup(e->port);
324
325     return r;
326 }
327
328 static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
329
330     pa_assert(a && b);
331
332     if (a->port_valid != b->port_valid ||
333         (a->port_valid && !pa_streq(a->port, b->port)))
334         return FALSE;
335
336     return TRUE;
337 }
338
339 static struct perportentry* perportentry_new(pa_bool_t add_pcm_format) {
340     struct perportentry *r = pa_xnew0(struct perportentry, 1);
341     r->version = PERPORTENTRY_VERSION;
342     r->formats = pa_idxset_new(NULL, NULL);
343     if (add_pcm_format) {
344         pa_format_info *f = pa_format_info_new();
345         f->encoding = PA_ENCODING_PCM;
346         pa_idxset_put(r->formats, f, NULL);
347     }
348     return r;
349 }
350
351 static void perportentry_free(struct perportentry* e) {
352     pa_assert(e);
353
354     pa_idxset_free(e->formats, (pa_free_cb_t) pa_format_info_free);
355     pa_xfree(e);
356 }
357
358 static pa_bool_t perportentry_write(struct userdata *u, const char *basekeyname, const char *port, const struct perportentry *e) {
359     pa_tagstruct *t;
360     pa_datum key, data;
361     pa_bool_t r;
362     uint32_t i;
363     pa_format_info *f;
364     uint8_t n_formats;
365     char *name;
366
367     pa_assert(u);
368     pa_assert(basekeyname);
369     pa_assert(e);
370
371     name = pa_sprintf_malloc("%s:%s", basekeyname, (port ? port : "null"));
372
373     n_formats = pa_idxset_size(e->formats);
374     pa_assert(n_formats > 0);
375
376     t = pa_tagstruct_new(NULL, 0);
377     pa_tagstruct_putu8(t, e->version);
378     pa_tagstruct_put_boolean(t, e->volume_valid);
379     pa_tagstruct_put_channel_map(t, &e->channel_map);
380     pa_tagstruct_put_cvolume(t, &e->volume);
381     pa_tagstruct_put_boolean(t, e->muted_valid);
382     pa_tagstruct_put_boolean(t, e->muted);
383     pa_tagstruct_putu8(t, n_formats);
384
385     PA_IDXSET_FOREACH(f, e->formats, i) {
386         pa_tagstruct_put_format_info(t, f);
387     }
388
389     key.data = (char *) name;
390     key.size = strlen(name);
391
392     data.data = (void*)pa_tagstruct_data(t, &data.size);
393
394     r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
395
396     pa_tagstruct_free(t);
397     pa_xfree(name);
398
399     return r;
400 }
401
402 static struct perportentry* perportentry_read(struct userdata *u, const char *basekeyname, const char *port) {
403     pa_datum key, data;
404     struct perportentry *e = NULL;
405     pa_tagstruct *t = NULL;
406     uint8_t i, n_formats;
407     char *name;
408
409     pa_assert(u);
410     pa_assert(basekeyname);
411
412     name = pa_sprintf_malloc("%s:%s", basekeyname, (port ? port : "null"));
413
414     key.data = name;
415     key.size = strlen(name);
416
417     pa_zero(data);
418
419     if (!pa_database_get(u->database, &key, &data))
420         goto fail;
421
422     t = pa_tagstruct_new(data.data, data.size);
423     e = perportentry_new(FALSE);
424
425     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
426         e->version > PERPORTENTRY_VERSION ||
427         pa_tagstruct_get_boolean(t, &e->volume_valid) < 0 ||
428         pa_tagstruct_get_channel_map(t, &e->channel_map) < 0 ||
429         pa_tagstruct_get_cvolume(t, &e->volume) < 0 ||
430         pa_tagstruct_get_boolean(t, &e->muted_valid) < 0 ||
431         pa_tagstruct_get_boolean(t, &e->muted) < 0 ||
432         pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
433
434         goto fail;
435     }
436
437     for (i = 0; i < n_formats; ++i) {
438         pa_format_info *f = pa_format_info_new();
439         if (pa_tagstruct_get_format_info(t, f) < 0) {
440             pa_format_info_free(f);
441             goto fail;
442         }
443         pa_idxset_put(e->formats, f, NULL);
444     }
445
446     if (!pa_tagstruct_eof(t))
447         goto fail;
448
449     if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
450         pa_log_warn("Invalid channel map stored in database for device %s", name);
451         goto fail;
452     }
453
454     if (e->volume_valid && (!pa_cvolume_valid(&e->volume) || !pa_cvolume_compatible_with_channel_map(&e->volume, &e->channel_map))) {
455         pa_log_warn("Volume and channel map don't match in database entry for device %s", name);
456         goto fail;
457     }
458
459     pa_tagstruct_free(t);
460     pa_datum_free(&data);
461     pa_xfree(name);
462
463     return e;
464
465 fail:
466
467     if (e)
468         perportentry_free(e);
469     if (t)
470         pa_tagstruct_free(t);
471
472     pa_datum_free(&data);
473
474 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
475     /* Try again with a null port. This is used when dealing with migration from older versions */
476     if (port) {
477         pa_xfree(name);
478         return perportentry_read(u, basekeyname, NULL);
479     }
480 #endif
481
482     pa_log_debug("Database contains invalid data for key: %s", name);
483
484     pa_xfree(name);
485
486     return NULL;
487 }
488
489 static struct perportentry* perportentry_copy(const struct perportentry *e) {
490     struct perportentry* r;
491     uint32_t idx;
492     pa_format_info *f;
493
494     pa_assert(e);
495     r = perportentry_new(FALSE);
496     r->version = e->version;
497     r->muted_valid = e->muted_valid;
498     r->volume_valid = e->volume_valid;
499     r->muted = e->muted;
500     r->channel_map = e->channel_map;
501     r->volume = e->volume;
502
503     PA_IDXSET_FOREACH(f, e->formats, idx) {
504         pa_idxset_put(r->formats, pa_format_info_copy(f), NULL);
505     }
506     return r;
507 }
508
509 static pa_bool_t perportentries_equal(const struct perportentry *a, const struct perportentry *b) {
510     pa_cvolume t;
511
512     pa_assert(a && b);
513
514     if (a->muted_valid != b->muted_valid ||
515         (a->muted_valid && (a->muted != b->muted)))
516         return FALSE;
517
518     t = b->volume;
519     if (a->volume_valid != b->volume_valid ||
520         (a->volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->volume)))
521         return FALSE;
522
523     if (pa_idxset_size(a->formats) != pa_idxset_size(b->formats))
524         return FALSE;
525
526     /** TODO: Compare a bit better */
527
528     return TRUE;
529 }
530
531 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
532
533 #define LEGACY_ENTRY_VERSION 2
534 static pa_bool_t legacy_entry_read(struct userdata *u, pa_datum *data, struct entry **entry, struct perportentry **perportentry) {
535     struct legacy_entry {
536         uint8_t version;
537         pa_bool_t muted_valid:1, volume_valid:1, port_valid:1;
538         pa_bool_t muted:1;
539         pa_channel_map channel_map;
540         pa_cvolume volume;
541         char port[PA_NAME_MAX];
542     } PA_GCC_PACKED;
543     struct legacy_entry *le;
544
545     pa_assert(u);
546     pa_assert(data);
547     pa_assert(entry);
548     pa_assert(perportentry);
549
550     if (data->size != sizeof(struct legacy_entry)) {
551         pa_log_debug("Size does not match.");
552         return FALSE;
553     }
554
555     le = (struct legacy_entry*)data->data;
556
557     if (le->version != LEGACY_ENTRY_VERSION) {
558         pa_log_debug("Version mismatch.");
559         return FALSE;
560     }
561
562     if (!memchr(le->port, 0, sizeof(le->port))) {
563         pa_log_warn("Port has missing NUL byte.");
564         return FALSE;
565     }
566
567     if (le->volume_valid && !pa_channel_map_valid(&le->channel_map)) {
568         pa_log_warn("Invalid channel map.");
569         return FALSE;
570     }
571
572     if (le->volume_valid && (!pa_cvolume_valid(&le->volume) || !pa_cvolume_compatible_with_channel_map(&le->volume, &le->channel_map))) {
573         pa_log_warn("Volume and channel map don't match.");
574         return FALSE;
575     }
576
577     *entry = entry_new();
578     (*entry)->port_valid = le->port_valid;
579     (*entry)->port = pa_xstrdup(le->port);
580
581     *perportentry = perportentry_new(TRUE);
582     (*perportentry)->muted_valid = le->muted_valid;
583     (*perportentry)->volume_valid = le->volume_valid;
584     (*perportentry)->muted = le->muted;
585     (*perportentry)->channel_map = le->channel_map;
586     (*perportentry)->volume = le->volume;
587
588     return TRUE;
589 }
590 #endif
591
592 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
593     struct userdata *u = userdata;
594     struct entry *e, *olde;
595     struct perportentry *ppe, *oldppe;
596     char *name;
597     const char *port = NULL;
598     pa_device_type_t type;
599     pa_bool_t written = FALSE;
600
601     pa_assert(c);
602     pa_assert(u);
603
604     if (t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW) &&
605         t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE) &&
606         t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW) &&
607         t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE))
608         return;
609
610     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) {
611         pa_sink *sink;
612
613         if (!(sink = pa_idxset_get_by_index(c->sinks, idx)))
614             return;
615
616         type = PA_DEVICE_TYPE_SINK;
617         name = pa_sprintf_malloc("sink:%s", sink->name);
618         if (sink->active_port)
619             port = sink->active_port->name;
620
621         if ((olde = entry_read(u, name)))
622             e = entry_copy(olde);
623         else
624             e = entry_new();
625
626         if (sink->save_port) {
627             pa_xfree(e->port);
628             e->port = pa_xstrdup(port ? port : "");
629             e->port_valid = TRUE;
630         }
631
632         if ((oldppe = perportentry_read(u, name, port)))
633             ppe = perportentry_copy(oldppe);
634         else
635             ppe = perportentry_new(TRUE);
636
637         if (sink->save_volume) {
638             ppe->channel_map = sink->channel_map;
639             ppe->volume = *pa_sink_get_volume(sink, FALSE);
640             ppe->volume_valid = TRUE;
641         }
642
643         if (sink->save_muted) {
644             ppe->muted = pa_sink_get_mute(sink, FALSE);
645             ppe->muted_valid = TRUE;
646         }
647     } else {
648         pa_source *source;
649
650         pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
651
652         if (!(source = pa_idxset_get_by_index(c->sources, idx)))
653             return;
654
655         type = PA_DEVICE_TYPE_SOURCE;
656         name = pa_sprintf_malloc("source:%s", source->name);
657         if (source->active_port)
658             port = source->active_port->name;
659
660         if ((olde = entry_read(u, name)))
661             e = entry_copy(olde);
662         else
663             e = entry_new();
664
665         if (source->save_port) {
666             pa_xfree(e->port);
667             e->port = pa_xstrdup(port ? port : "");
668             e->port_valid = TRUE;
669         }
670
671         if ((oldppe = perportentry_read(u, name, port)))
672             ppe = perportentry_copy(oldppe);
673         else
674             ppe = perportentry_new(TRUE);
675
676         if (source->save_volume) {
677             ppe->channel_map = source->channel_map;
678             ppe->volume = *pa_source_get_volume(source, FALSE);
679             ppe->volume_valid = TRUE;
680         }
681
682         if (source->save_muted) {
683             ppe->muted = pa_source_get_mute(source, FALSE);
684             ppe->muted_valid = TRUE;
685         }
686     }
687
688
689     pa_assert(e);
690
691     if (olde) {
692
693         if (entries_equal(olde, e)) {
694             entry_free(olde);
695             entry_free(e);
696             e = NULL;
697         } else
698             entry_free(olde);
699     }
700
701     if (e) {
702         pa_log_info("Storing port for device %s.", name);
703
704         written = entry_write(u, name, e);
705
706         entry_free(e);
707     }
708
709
710     pa_assert(ppe);
711
712     if (oldppe) {
713
714         if (perportentries_equal(oldppe, ppe)) {
715             perportentry_free(oldppe);
716             perportentry_free(ppe);
717             ppe = NULL;
718         } else
719             perportentry_free(oldppe);
720     }
721
722     if (ppe) {
723         pa_log_info("Storing volume/mute for device+port %s:%s.", name, (port ? port : "null"));
724
725         written = perportentry_write(u, name, port, ppe) || written;
726
727         perportentry_free(ppe);
728     }
729     pa_xfree(name);
730
731     if (written)
732         trigger_save(u, type, idx);
733 }
734
735 static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
736     char *name;
737     struct entry *e;
738
739     pa_assert(c);
740     pa_assert(new_data);
741     pa_assert(u);
742     pa_assert(u->restore_port);
743
744     name = pa_sprintf_malloc("sink:%s", new_data->name);
745
746     if ((e = entry_read(u, name))) {
747
748         if (e->port_valid) {
749             if (!new_data->active_port) {
750                 pa_log_info("Restoring port for sink %s.", name);
751                 pa_sink_new_data_set_port(new_data, e->port);
752                 new_data->save_port = TRUE;
753             } else
754                 pa_log_debug("Not restoring port for sink %s, because already set.", name);
755         }
756
757         entry_free(e);
758     }
759
760     pa_xfree(name);
761
762     return PA_HOOK_OK;
763 }
764
765 static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
766     char *name;
767     struct perportentry *e;
768
769     pa_assert(c);
770     pa_assert(new_data);
771     pa_assert(u);
772     pa_assert(u->restore_volume || u->restore_muted);
773
774     name = pa_sprintf_malloc("sink:%s", new_data->name);
775
776     if ((e = perportentry_read(u, name, new_data->active_port))) {
777
778         if (u->restore_volume && e->volume_valid) {
779
780             if (!new_data->volume_is_set) {
781                 pa_cvolume v;
782                 char buf[PA_CVOLUME_SNPRINT_MAX];
783
784                 pa_log_info("Restoring volume for sink %s.", new_data->name);
785                 v = e->volume;
786                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
787                 pa_sink_new_data_set_volume(new_data, &v);
788                 pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &new_data->volume));
789
790                 new_data->save_volume = TRUE;
791             } else
792                 pa_log_debug("Not restoring volume for sink %s, because already set.", new_data->name);
793         }
794
795         if (u->restore_muted && e->muted_valid) {
796
797             if (!new_data->muted_is_set) {
798                 pa_log_info("Restoring mute state for sink %s.", new_data->name);
799                 pa_sink_new_data_set_muted(new_data, e->muted);
800                 new_data->save_muted = TRUE;
801             } else
802                 pa_log_debug("Not restoring mute state for sink %s, because already set.", new_data->name);
803         }
804
805         perportentry_free(e);
806     }
807
808     pa_xfree(name);
809
810     return PA_HOOK_OK;
811 }
812
813 static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
814     char *name;
815     struct perportentry *e;
816
817     pa_assert(c);
818     pa_assert(sink);
819     pa_assert(u);
820     pa_assert(u->restore_volume || u->restore_muted);
821
822     name = pa_sprintf_malloc("sink:%s", sink->name);
823
824     if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
825
826         if (u->restore_volume && e->volume_valid) {
827             pa_cvolume v;
828             char buf[PA_CVOLUME_SNPRINT_MAX];
829
830             pa_log_info("Restoring volume for sink %s.", sink->name);
831             v = e->volume;
832             pa_cvolume_remap(&v, &e->channel_map, &sink->channel_map);
833             pa_sink_set_volume(sink, &v, TRUE, FALSE);
834             pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &sink->reference_volume));
835
836             sink->save_volume = TRUE;
837         }
838
839         if (u->restore_muted && e->muted_valid) {
840
841             pa_log_info("Restoring mute state for sink %s.", sink->name);
842             pa_sink_set_mute(sink, e->muted, FALSE);
843             sink->save_muted = TRUE;
844         }
845
846         perportentry_free(e);
847     }
848
849     pa_xfree(name);
850
851     return PA_HOOK_OK;
852 }
853
854 static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
855     char *name;
856     struct perportentry *e;
857
858     pa_assert(c);
859     pa_assert(sink);
860     pa_assert(u);
861     pa_assert(u->restore_formats);
862
863     name = pa_sprintf_malloc("sink:%s", sink->name);
864
865     if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
866
867         if (!pa_sink_set_formats(sink, e->formats))
868             pa_log_debug("Could not set format on sink %s", sink->name);
869
870         perportentry_free(e);
871     }
872
873     pa_xfree(name);
874
875     return PA_HOOK_OK;
876 }
877
878 static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
879     char *name;
880     struct entry *e;
881
882     pa_assert(c);
883     pa_assert(new_data);
884     pa_assert(u);
885     pa_assert(u->restore_port);
886
887     name = pa_sprintf_malloc("source:%s", new_data->name);
888
889     if ((e = entry_read(u, name))) {
890
891         if (e->port_valid) {
892             if (!new_data->active_port) {
893                 pa_log_info("Restoring port for source %s.", name);
894                 pa_source_new_data_set_port(new_data, e->port);
895                 new_data->save_port = TRUE;
896             } else
897                 pa_log_debug("Not restoring port for source %s, because already set.", name);
898         }
899
900         entry_free(e);
901     }
902
903     pa_xfree(name);
904
905     return PA_HOOK_OK;
906 }
907
908 static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
909     char *name;
910     struct perportentry *e;
911
912     pa_assert(c);
913     pa_assert(new_data);
914     pa_assert(u);
915     pa_assert(u->restore_volume || u->restore_muted);
916
917     name = pa_sprintf_malloc("source:%s", new_data->name);
918
919     if ((e = perportentry_read(u, name, new_data->active_port))) {
920
921         if (u->restore_volume && e->volume_valid) {
922
923             if (!new_data->volume_is_set) {
924                 pa_cvolume v;
925                 char buf[PA_CVOLUME_SNPRINT_MAX];
926
927                 pa_log_info("Restoring volume for source %s.", new_data->name);
928                 v = e->volume;
929                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
930                 pa_source_new_data_set_volume(new_data, &v);
931                 pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &new_data->volume));
932
933                 new_data->save_volume = TRUE;
934             } else
935                 pa_log_debug("Not restoring volume for source %s, because already set.", new_data->name);
936         }
937
938         if (u->restore_muted && e->muted_valid) {
939
940             if (!new_data->muted_is_set) {
941                 pa_log_info("Restoring mute state for source %s.", new_data->name);
942                 pa_source_new_data_set_muted(new_data, e->muted);
943                 new_data->save_muted = TRUE;
944             } else
945                 pa_log_debug("Not restoring mute state for source %s, because already set.", new_data->name);
946         }
947
948         perportentry_free(e);
949     }
950
951     pa_xfree(name);
952
953     return PA_HOOK_OK;
954 }
955
956 static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
957     char *name;
958     struct perportentry *e;
959
960     pa_assert(c);
961     pa_assert(source);
962     pa_assert(u);
963     pa_assert(u->restore_volume || u->restore_muted);
964
965     name = pa_sprintf_malloc("source:%s", source->name);
966
967     if ((e = perportentry_read(u, name, (source->active_port ? source->active_port->name : NULL)))) {
968
969         if (u->restore_volume && e->volume_valid) {
970             pa_cvolume v;
971             char buf[PA_CVOLUME_SNPRINT_MAX];
972
973             pa_log_info("Restoring volume for source %s.", source->name);
974             v = e->volume;
975             pa_cvolume_remap(&v, &e->channel_map, &source->channel_map);
976             pa_source_set_volume(source, &v, TRUE, FALSE);
977             pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &source->reference_volume));
978
979             source->save_volume = TRUE;
980         }
981
982         if (u->restore_muted && e->muted_valid) {
983
984             pa_log_info("Restoring mute state for source %s.", source->name);
985             pa_source_set_mute(source, e->muted, FALSE);
986             source->save_muted = TRUE;
987         }
988
989         perportentry_free(e);
990     }
991
992     pa_xfree(name);
993
994     return PA_HOOK_OK;
995 }
996
997 #define EXT_VERSION 1
998
999 static void read_sink_format_reply(struct userdata *u, pa_tagstruct *reply, pa_sink *sink) {
1000     struct perportentry *e;
1001     char *name;
1002
1003     pa_assert(u);
1004     pa_assert(reply);
1005     pa_assert(sink);
1006
1007     pa_tagstruct_putu32(reply, PA_DEVICE_TYPE_SINK);
1008     pa_tagstruct_putu32(reply, sink->index);
1009
1010     /* Read or create an entry */
1011     name = pa_sprintf_malloc("sink:%s", sink->name);
1012     if (!(e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
1013         /* Fake a reply with PCM encoding supported */
1014         pa_format_info *f = pa_format_info_new();
1015
1016         pa_tagstruct_putu8(reply, 1);
1017         f->encoding = PA_ENCODING_PCM;
1018         pa_tagstruct_put_format_info(reply, f);
1019
1020         pa_format_info_free(f);
1021     } else {
1022         uint32_t idx;
1023         pa_format_info *f;
1024
1025         /* Write all the formats from the entry to the reply */
1026         pa_tagstruct_putu8(reply, pa_idxset_size(e->formats));
1027         PA_IDXSET_FOREACH(f, e->formats, idx) {
1028             pa_tagstruct_put_format_info(reply, f);
1029         }
1030     }
1031     pa_xfree(name);
1032 }
1033
1034 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
1035     struct userdata *u;
1036     uint32_t command;
1037     pa_tagstruct *reply = NULL;
1038
1039     pa_assert(p);
1040     pa_assert(m);
1041     pa_assert(c);
1042     pa_assert(t);
1043
1044     u = m->userdata;
1045
1046     if (pa_tagstruct_getu32(t, &command) < 0)
1047         goto fail;
1048
1049     reply = pa_tagstruct_new(NULL, 0);
1050     pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
1051     pa_tagstruct_putu32(reply, tag);
1052
1053     switch (command) {
1054         case SUBCOMMAND_TEST: {
1055             if (!pa_tagstruct_eof(t))
1056                 goto fail;
1057
1058             pa_tagstruct_putu32(reply, EXT_VERSION);
1059             break;
1060         }
1061
1062         case SUBCOMMAND_SUBSCRIBE: {
1063
1064             pa_bool_t enabled;
1065
1066             if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
1067                 !pa_tagstruct_eof(t))
1068                 goto fail;
1069
1070             if (enabled)
1071                 pa_idxset_put(u->subscribed, c, NULL);
1072             else
1073                 pa_idxset_remove_by_data(u->subscribed, c, NULL);
1074
1075             break;
1076         }
1077
1078         case SUBCOMMAND_READ_FORMATS_ALL: {
1079             pa_sink *sink;
1080             uint32_t idx;
1081
1082             if (!pa_tagstruct_eof(t))
1083                 goto fail;
1084
1085             PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
1086                 read_sink_format_reply(u, reply, sink);
1087             }
1088
1089             break;
1090         }
1091         case SUBCOMMAND_READ_FORMATS: {
1092             pa_device_type_t type;
1093             uint32_t sink_index;
1094             pa_sink *sink;
1095
1096             pa_assert(reply);
1097
1098             /* Get the sink index and the number of formats from the tagstruct */
1099             if (pa_tagstruct_getu32(t, &type) < 0 ||
1100                 pa_tagstruct_getu32(t, &sink_index) < 0)
1101                 goto fail;
1102
1103             if (type != PA_DEVICE_TYPE_SINK) {
1104                 pa_log("Device format reading is only supported on sinks");
1105                 goto fail;
1106             }
1107
1108             if (!pa_tagstruct_eof(t))
1109                 goto fail;
1110
1111             /* Now find our sink */
1112             if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index)))
1113                 goto fail;
1114
1115             read_sink_format_reply(u, reply, sink);
1116
1117             break;
1118         }
1119
1120         case SUBCOMMAND_SAVE_FORMATS: {
1121
1122             struct perportentry *e;
1123             pa_device_type_t type;
1124             uint32_t sink_index;
1125             char *name;
1126             pa_sink *sink;
1127             uint8_t i, n_formats;
1128
1129             /* Get the sink index and the number of formats from the tagstruct */
1130             if (pa_tagstruct_getu32(t, &type) < 0 ||
1131                 pa_tagstruct_getu32(t, &sink_index) < 0 ||
1132                 pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
1133
1134                 goto fail;
1135             }
1136
1137             if (type != PA_DEVICE_TYPE_SINK) {
1138                 pa_log("Device format saving is only supported on sinks");
1139                 goto fail;
1140             }
1141
1142             /* Now find our sink */
1143             if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index))) {
1144                 pa_log("Could not find sink #%d", sink_index);
1145                 goto fail;
1146             }
1147
1148             /* Read or create an entry */
1149             name = pa_sprintf_malloc("sink:%s", sink->name);
1150             if (!(e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL))))
1151                 e = perportentry_new(FALSE);
1152             else {
1153                 /* Clean out any saved formats */
1154                 pa_idxset_free(e->formats, (pa_free_cb_t) pa_format_info_free);
1155                 e->formats = pa_idxset_new(NULL, NULL);
1156             }
1157
1158             /* Read all the formats from our tagstruct */
1159             for (i = 0; i < n_formats; ++i) {
1160                 pa_format_info *f = pa_format_info_new();
1161                 if (pa_tagstruct_get_format_info(t, f) < 0) {
1162                     pa_format_info_free(f);
1163                     pa_xfree(name);
1164                     goto fail;
1165                 }
1166                 pa_idxset_put(e->formats, f, NULL);
1167             }
1168
1169             if (!pa_tagstruct_eof(t)) {
1170                 perportentry_free(e);
1171                 pa_xfree(name);
1172                 goto fail;
1173             }
1174
1175             if (pa_sink_set_formats(sink, e->formats) && perportentry_write(u, name, (sink->active_port ? sink->active_port->name : NULL), e))
1176                 trigger_save(u, type, sink_index);
1177             else
1178                 pa_log_warn("Could not save format info for sink %s", sink->name);
1179
1180             pa_xfree(name);
1181             perportentry_free(e);
1182
1183             break;
1184         }
1185
1186         default:
1187             goto fail;
1188     }
1189
1190     pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
1191     return 0;
1192
1193 fail:
1194
1195     if (reply)
1196         pa_tagstruct_free(reply);
1197
1198     return -1;
1199 }
1200
1201 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
1202     pa_assert(p);
1203     pa_assert(c);
1204     pa_assert(u);
1205
1206     pa_idxset_remove_by_data(u->subscribed, c, NULL);
1207     return PA_HOOK_OK;
1208 }
1209
1210 int pa__init(pa_module*m) {
1211     pa_modargs *ma = NULL;
1212     struct userdata *u;
1213     char *fname;
1214     pa_sink *sink;
1215     pa_source *source;
1216     uint32_t idx;
1217     pa_bool_t restore_volume = TRUE, restore_muted = TRUE, restore_port = TRUE, restore_formats = TRUE;
1218
1219     pa_assert(m);
1220
1221     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1222         pa_log("Failed to parse module arguments");
1223         goto fail;
1224     }
1225
1226     if (pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
1227         pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
1228         pa_modargs_get_value_boolean(ma, "restore_port", &restore_port) < 0 ||
1229         pa_modargs_get_value_boolean(ma, "restore_formats", &restore_formats) < 0) {
1230         pa_log("restore_port, restore_volume, restore_muted and restore_formats expect boolean arguments");
1231         goto fail;
1232     }
1233
1234     if (!restore_muted && !restore_volume && !restore_port && !restore_formats)
1235         pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring port enabled!");
1236
1237     m->userdata = u = pa_xnew0(struct userdata, 1);
1238     u->core = m->core;
1239     u->module = m;
1240     u->restore_volume = restore_volume;
1241     u->restore_muted = restore_muted;
1242     u->restore_port = restore_port;
1243     u->restore_formats = restore_formats;
1244
1245     u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
1246
1247     u->protocol = pa_native_protocol_get(m->core);
1248     pa_native_protocol_install_ext(u->protocol, m, extension_cb);
1249
1250     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);
1251
1252     u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE, subscribe_callback, u);
1253
1254     if (restore_port) {
1255         u->sink_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) sink_new_hook_callback, u);
1256         u->source_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) source_new_hook_callback, u);
1257     }
1258
1259     if (restore_muted || restore_volume) {
1260         u->sink_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_fixate_hook_callback, u);
1261         u->source_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_fixate_hook_callback, u);
1262
1263         u->sink_port_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) sink_port_hook_callback, u);
1264         u->source_port_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) source_port_hook_callback, u);
1265     }
1266
1267     if (restore_formats)
1268         u->sink_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) sink_put_hook_callback, u);
1269
1270     if (!(fname = pa_state_path("device-volumes", TRUE)))
1271         goto fail;
1272
1273     if (!(u->database = pa_database_open(fname, TRUE))) {
1274         pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
1275         pa_xfree(fname);
1276         goto fail;
1277     }
1278
1279     pa_log_info("Successfully opened database file '%s'.", fname);
1280     pa_xfree(fname);
1281
1282     PA_IDXSET_FOREACH(sink, m->core->sinks, idx)
1283         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);
1284
1285     PA_IDXSET_FOREACH(source, m->core->sources, idx)
1286         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, source->index, u);
1287
1288     pa_modargs_free(ma);
1289     return 0;
1290
1291 fail:
1292     pa__done(m);
1293
1294     if (ma)
1295         pa_modargs_free(ma);
1296
1297     return -1;
1298 }
1299
1300 void pa__done(pa_module*m) {
1301     struct userdata* u;
1302
1303     pa_assert(m);
1304
1305     if (!(u = m->userdata))
1306         return;
1307
1308     if (u->subscription)
1309         pa_subscription_free(u->subscription);
1310
1311     if (u->sink_fixate_hook_slot)
1312         pa_hook_slot_free(u->sink_fixate_hook_slot);
1313     if (u->source_fixate_hook_slot)
1314         pa_hook_slot_free(u->source_fixate_hook_slot);
1315     if (u->sink_new_hook_slot)
1316         pa_hook_slot_free(u->sink_new_hook_slot);
1317     if (u->source_new_hook_slot)
1318         pa_hook_slot_free(u->source_new_hook_slot);
1319     if (u->sink_port_hook_slot)
1320         pa_hook_slot_free(u->sink_port_hook_slot);
1321     if (u->source_port_hook_slot)
1322         pa_hook_slot_free(u->source_port_hook_slot);
1323     if (u->sink_put_hook_slot)
1324         pa_hook_slot_free(u->sink_put_hook_slot);
1325
1326     if (u->connection_unlink_hook_slot)
1327         pa_hook_slot_free(u->connection_unlink_hook_slot);
1328
1329     if (u->save_time_event)
1330         u->core->mainloop->time_free(u->save_time_event);
1331
1332     if (u->database)
1333         pa_database_close(u->database);
1334
1335     if (u->protocol) {
1336         pa_native_protocol_remove_ext(u->protocol, m);
1337         pa_native_protocol_unref(u->protocol);
1338     }
1339
1340     if (u->subscribed)
1341         pa_idxset_free(u->subscribed, NULL);
1342
1343     pa_xfree(u);
1344 }