release: updated changelog.
[profile/ivi/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         for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(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() {
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(FALSE);
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_free2_cb_t) pa_format_info_free2, NULL);
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
783                 pa_log_info("Restoring volume for sink %s.", new_data->name);
784
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
789                 new_data->save_volume = TRUE;
790             } else
791                 pa_log_debug("Not restoring volume for sink %s, because already set.", new_data->name);
792         }
793
794         if (u->restore_muted && e->muted_valid) {
795
796             if (!new_data->muted_is_set) {
797                 pa_log_info("Restoring mute state for sink %s.", new_data->name);
798                 pa_sink_new_data_set_muted(new_data, e->muted);
799                 new_data->save_muted = TRUE;
800             } else
801                 pa_log_debug("Not restoring mute state for sink %s, because already set.", new_data->name);
802         }
803
804         perportentry_free(e);
805     }
806
807     pa_xfree(name);
808
809     return PA_HOOK_OK;
810 }
811
812 static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
813     char *name;
814     struct perportentry *e;
815
816     pa_assert(c);
817     pa_assert(sink);
818     pa_assert(u);
819     pa_assert(u->restore_volume || u->restore_muted);
820
821     name = pa_sprintf_malloc("sink:%s", sink->name);
822
823     if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
824
825         if (u->restore_volume && e->volume_valid) {
826
827             pa_cvolume v;
828
829             pa_log_info("Restoring volume for sink %s.", sink->name);
830
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             sink->save_volume = TRUE;
835         }
836
837         if (u->restore_muted && e->muted_valid) {
838
839             pa_log_info("Restoring mute state for sink %s.", sink->name);
840             pa_sink_set_mute(sink, e->muted, FALSE);
841             sink->save_muted = TRUE;
842         }
843
844         perportentry_free(e);
845     }
846
847     pa_xfree(name);
848
849     return PA_HOOK_OK;
850 }
851
852 static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
853     char *name;
854     struct perportentry *e;
855
856     pa_assert(c);
857     pa_assert(sink);
858     pa_assert(u);
859     pa_assert(u->restore_formats);
860
861     name = pa_sprintf_malloc("sink:%s", sink->name);
862
863     if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
864
865         if (!pa_sink_set_formats(sink, e->formats))
866             pa_log_debug("Could not set format on sink %s", sink->name);
867
868         perportentry_free(e);
869     }
870
871     pa_xfree(name);
872
873     return PA_HOOK_OK;
874 }
875
876 static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
877     char *name;
878     struct entry *e;
879
880     pa_assert(c);
881     pa_assert(new_data);
882     pa_assert(u);
883     pa_assert(u->restore_port);
884
885     name = pa_sprintf_malloc("source:%s", new_data->name);
886
887     if ((e = entry_read(u, name))) {
888
889         if (e->port_valid) {
890             if (!new_data->active_port) {
891                 pa_log_info("Restoring port for source %s.", name);
892                 pa_source_new_data_set_port(new_data, e->port);
893                 new_data->save_port = TRUE;
894             } else
895                 pa_log_debug("Not restoring port for source %s, because already set.", name);
896         }
897
898         entry_free(e);
899     }
900
901     pa_xfree(name);
902
903     return PA_HOOK_OK;
904 }
905
906 static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
907     char *name;
908     struct perportentry *e;
909
910     pa_assert(c);
911     pa_assert(new_data);
912     pa_assert(u);
913     pa_assert(u->restore_volume || u->restore_muted);
914
915     name = pa_sprintf_malloc("source:%s", new_data->name);
916
917     if ((e = perportentry_read(u, name, new_data->active_port))) {
918
919         if (u->restore_volume && e->volume_valid) {
920
921             if (!new_data->volume_is_set) {
922                 pa_cvolume v;
923
924                 pa_log_info("Restoring volume for source %s.", new_data->name);
925
926                 v = e->volume;
927                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
928                 pa_source_new_data_set_volume(new_data, &v);
929
930                 new_data->save_volume = TRUE;
931             } else
932                 pa_log_debug("Not restoring volume for source %s, because already set.", new_data->name);
933         }
934
935         if (u->restore_muted && e->muted_valid) {
936
937             if (!new_data->muted_is_set) {
938                 pa_log_info("Restoring mute state for source %s.", new_data->name);
939                 pa_source_new_data_set_muted(new_data, e->muted);
940                 new_data->save_muted = TRUE;
941             } else
942                 pa_log_debug("Not restoring mute state for source %s, because already set.", new_data->name);
943         }
944
945         perportentry_free(e);
946     }
947
948     pa_xfree(name);
949
950     return PA_HOOK_OK;
951 }
952
953 static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
954     char *name;
955     struct perportentry *e;
956
957     pa_assert(c);
958     pa_assert(source);
959     pa_assert(u);
960     pa_assert(u->restore_volume || u->restore_muted);
961
962     name = pa_sprintf_malloc("source:%s", source->name);
963
964     if ((e = perportentry_read(u, name, (source->active_port ? source->active_port->name : NULL)))) {
965
966         if (u->restore_volume && e->volume_valid) {
967
968             pa_cvolume v;
969
970             pa_log_info("Restoring volume for source %s.", source->name);
971
972             v = e->volume;
973             pa_cvolume_remap(&v, &e->channel_map, &source->channel_map);
974             pa_source_set_volume(source, &v, TRUE, FALSE);
975             source->save_volume = TRUE;
976         }
977
978         if (u->restore_muted && e->muted_valid) {
979
980             pa_log_info("Restoring mute state for source %s.", source->name);
981             pa_source_set_mute(source, e->muted, FALSE);
982             source->save_muted = TRUE;
983         }
984
985         perportentry_free(e);
986     }
987
988     pa_xfree(name);
989
990     return PA_HOOK_OK;
991 }
992
993 #define EXT_VERSION 1
994
995 static void read_sink_format_reply(struct userdata *u, pa_tagstruct *reply, pa_sink *sink) {
996     struct perportentry *e;
997     char *name;
998
999     pa_assert(u);
1000     pa_assert(reply);
1001     pa_assert(sink);
1002
1003     pa_tagstruct_putu32(reply, PA_DEVICE_TYPE_SINK);
1004     pa_tagstruct_putu32(reply, sink->index);
1005
1006     /* Read or create an entry */
1007     name = pa_sprintf_malloc("sink:%s", sink->name);
1008     if (!(e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
1009         /* Fake a reply with PCM encoding supported */
1010         pa_format_info *f = pa_format_info_new();
1011
1012         pa_tagstruct_putu8(reply, 1);
1013         f->encoding = PA_ENCODING_PCM;
1014         pa_tagstruct_put_format_info(reply, f);
1015
1016         pa_format_info_free(f);
1017     } else {
1018         uint32_t idx;
1019         pa_format_info *f;
1020
1021         /* Write all the formats from the entry to the reply */
1022         pa_tagstruct_putu8(reply, pa_idxset_size(e->formats));
1023         PA_IDXSET_FOREACH(f, e->formats, idx) {
1024             pa_tagstruct_put_format_info(reply, f);
1025         }
1026     }
1027     pa_xfree(name);
1028 }
1029
1030 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
1031     struct userdata *u;
1032     uint32_t command;
1033     pa_tagstruct *reply = NULL;
1034
1035     pa_assert(p);
1036     pa_assert(m);
1037     pa_assert(c);
1038     pa_assert(t);
1039
1040     u = m->userdata;
1041
1042     if (pa_tagstruct_getu32(t, &command) < 0)
1043         goto fail;
1044
1045     reply = pa_tagstruct_new(NULL, 0);
1046     pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
1047     pa_tagstruct_putu32(reply, tag);
1048
1049     switch (command) {
1050         case SUBCOMMAND_TEST: {
1051             if (!pa_tagstruct_eof(t))
1052                 goto fail;
1053
1054             pa_tagstruct_putu32(reply, EXT_VERSION);
1055             break;
1056         }
1057
1058         case SUBCOMMAND_SUBSCRIBE: {
1059
1060             pa_bool_t enabled;
1061
1062             if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
1063                 !pa_tagstruct_eof(t))
1064                 goto fail;
1065
1066             if (enabled)
1067                 pa_idxset_put(u->subscribed, c, NULL);
1068             else
1069                 pa_idxset_remove_by_data(u->subscribed, c, NULL);
1070
1071             break;
1072         }
1073
1074         case SUBCOMMAND_READ_FORMATS_ALL: {
1075             pa_sink *sink;
1076             uint32_t idx;
1077
1078             if (!pa_tagstruct_eof(t))
1079                 goto fail;
1080
1081             PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
1082                 read_sink_format_reply(u, reply, sink);
1083             }
1084
1085             break;
1086         }
1087         case SUBCOMMAND_READ_FORMATS: {
1088             pa_device_type_t type;
1089             uint32_t sink_index;
1090             pa_sink *sink;
1091
1092             pa_assert(reply);
1093
1094             /* Get the sink index and the number of formats from the tagstruct */
1095             if (pa_tagstruct_getu32(t, &type) < 0 ||
1096                 pa_tagstruct_getu32(t, &sink_index) < 0)
1097                 goto fail;
1098
1099             if (type != PA_DEVICE_TYPE_SINK) {
1100                 pa_log("Device format reading is only supported on sinks");
1101                 goto fail;
1102             }
1103
1104             if (!pa_tagstruct_eof(t))
1105                 goto fail;
1106
1107             /* Now find our sink */
1108             if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index)))
1109                 goto fail;
1110
1111             read_sink_format_reply(u, reply, sink);
1112
1113             break;
1114         }
1115
1116         case SUBCOMMAND_SAVE_FORMATS: {
1117
1118             struct perportentry *e;
1119             pa_device_type_t type;
1120             uint32_t sink_index;
1121             char *name;
1122             pa_sink *sink;
1123             uint8_t i, n_formats;
1124
1125             /* Get the sink index and the number of formats from the tagstruct */
1126             if (pa_tagstruct_getu32(t, &type) < 0 ||
1127                 pa_tagstruct_getu32(t, &sink_index) < 0 ||
1128                 pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
1129
1130                 goto fail;
1131             }
1132
1133             if (type != PA_DEVICE_TYPE_SINK) {
1134                 pa_log("Device format saving is only supported on sinks");
1135                 goto fail;
1136             }
1137
1138             /* Now find our sink */
1139             if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index))) {
1140                 pa_log("Could not find sink #%d", sink_index);
1141                 goto fail;
1142             }
1143
1144             /* Read or create an entry */
1145             name = pa_sprintf_malloc("sink:%s", sink->name);
1146             if (!(e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL))))
1147                 e = perportentry_new(FALSE);
1148             else {
1149                 /* Clean out any saved formats */
1150                 pa_idxset_free(e->formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
1151                 e->formats = pa_idxset_new(NULL, NULL);
1152             }
1153
1154             /* Read all the formats from our tagstruct */
1155             for (i = 0; i < n_formats; ++i) {
1156                 pa_format_info *f = pa_format_info_new();
1157                 if (pa_tagstruct_get_format_info(t, f) < 0) {
1158                     pa_format_info_free(f);
1159                     pa_xfree(name);
1160                     goto fail;
1161                 }
1162                 pa_idxset_put(e->formats, f, NULL);
1163             }
1164
1165             if (!pa_tagstruct_eof(t)) {
1166                 perportentry_free(e);
1167                 pa_xfree(name);
1168                 goto fail;
1169             }
1170
1171             if (pa_sink_set_formats(sink, e->formats) && perportentry_write(u, name, (sink->active_port ? sink->active_port->name : NULL), e))
1172                 trigger_save(u, type, sink_index);
1173             else
1174                 pa_log_warn("Could not save format info for sink %s", sink->name);
1175
1176             pa_xfree(name);
1177             perportentry_free(e);
1178
1179             break;
1180         }
1181
1182         default:
1183             goto fail;
1184     }
1185
1186     pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
1187     return 0;
1188
1189 fail:
1190
1191     if (reply)
1192         pa_tagstruct_free(reply);
1193
1194     return -1;
1195 }
1196
1197 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
1198     pa_assert(p);
1199     pa_assert(c);
1200     pa_assert(u);
1201
1202     pa_idxset_remove_by_data(u->subscribed, c, NULL);
1203     return PA_HOOK_OK;
1204 }
1205
1206 int pa__init(pa_module*m) {
1207     pa_modargs *ma = NULL;
1208     struct userdata *u;
1209     char *fname;
1210     pa_sink *sink;
1211     pa_source *source;
1212     uint32_t idx;
1213     pa_bool_t restore_volume = TRUE, restore_muted = TRUE, restore_port = TRUE, restore_formats = TRUE;
1214
1215     pa_assert(m);
1216
1217     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
1218         pa_log("Failed to parse module arguments");
1219         goto fail;
1220     }
1221
1222     if (pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
1223         pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
1224         pa_modargs_get_value_boolean(ma, "restore_port", &restore_port) < 0 ||
1225         pa_modargs_get_value_boolean(ma, "restore_formats", &restore_formats) < 0) {
1226         pa_log("restore_port, restore_volume, restore_muted and restore_formats expect boolean arguments");
1227         goto fail;
1228     }
1229
1230     if (!restore_muted && !restore_volume && !restore_port && !restore_formats)
1231         pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring port enabled!");
1232
1233     m->userdata = u = pa_xnew0(struct userdata, 1);
1234     u->core = m->core;
1235     u->module = m;
1236     u->restore_volume = restore_volume;
1237     u->restore_muted = restore_muted;
1238     u->restore_port = restore_port;
1239     u->restore_formats = restore_formats;
1240
1241     u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
1242
1243     u->protocol = pa_native_protocol_get(m->core);
1244     pa_native_protocol_install_ext(u->protocol, m, extension_cb);
1245
1246     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);
1247
1248     u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE, subscribe_callback, u);
1249
1250     if (restore_port) {
1251         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);
1252         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);
1253     }
1254
1255     if (restore_muted || restore_volume) {
1256         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);
1257         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);
1258
1259         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);
1260         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);
1261     }
1262
1263     if (restore_formats)
1264         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);
1265
1266     if (!(fname = pa_state_path("device-volumes", TRUE)))
1267         goto fail;
1268
1269     if (!(u->database = pa_database_open(fname, TRUE))) {
1270         pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
1271         pa_xfree(fname);
1272         goto fail;
1273     }
1274
1275     pa_log_info("Successfully opened database file '%s'.", fname);
1276     pa_xfree(fname);
1277
1278     for (sink = pa_idxset_first(m->core->sinks, &idx); sink; sink = pa_idxset_next(m->core->sinks, &idx))
1279         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);
1280
1281     for (source = pa_idxset_first(m->core->sources, &idx); source; source = pa_idxset_next(m->core->sources, &idx))
1282         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, source->index, u);
1283
1284     pa_modargs_free(ma);
1285     return 0;
1286
1287 fail:
1288     pa__done(m);
1289
1290     if (ma)
1291         pa_modargs_free(ma);
1292
1293     return -1;
1294 }
1295
1296 void pa__done(pa_module*m) {
1297     struct userdata* u;
1298
1299     pa_assert(m);
1300
1301     if (!(u = m->userdata))
1302         return;
1303
1304     if (u->subscription)
1305         pa_subscription_free(u->subscription);
1306
1307     if (u->sink_fixate_hook_slot)
1308         pa_hook_slot_free(u->sink_fixate_hook_slot);
1309     if (u->source_fixate_hook_slot)
1310         pa_hook_slot_free(u->source_fixate_hook_slot);
1311     if (u->sink_new_hook_slot)
1312         pa_hook_slot_free(u->sink_new_hook_slot);
1313     if (u->source_new_hook_slot)
1314         pa_hook_slot_free(u->source_new_hook_slot);
1315     if (u->sink_port_hook_slot)
1316         pa_hook_slot_free(u->sink_port_hook_slot);
1317     if (u->source_port_hook_slot)
1318         pa_hook_slot_free(u->source_port_hook_slot);
1319     if (u->sink_put_hook_slot)
1320         pa_hook_slot_free(u->sink_put_hook_slot);
1321
1322     if (u->connection_unlink_hook_slot)
1323         pa_hook_slot_free(u->connection_unlink_hook_slot);
1324
1325     if (u->save_time_event)
1326         u->core->mainloop->time_free(u->save_time_event);
1327
1328     if (u->database)
1329         pa_database_close(u->database);
1330
1331     if (u->protocol) {
1332         pa_native_protocol_remove_ext(u->protocol, m);
1333         pa_native_protocol_unref(u->protocol);
1334     }
1335
1336     if (u->subscribed)
1337         pa_idxset_free(u->subscribed, NULL, NULL);
1338
1339     pa_xfree(u);
1340 }