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