Remove unnecessary #includes
[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
68 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
69
70 static const char* const valid_modargs[] = {
71     "restore_volume",
72     "restore_muted",
73     "restore_port",
74     NULL
75 };
76
77 struct userdata {
78     pa_core *core;
79     pa_module *module;
80     pa_subscription *subscription;
81     pa_hook_slot
82         *sink_new_hook_slot,
83         *sink_fixate_hook_slot,
84         *source_new_hook_slot,
85         *source_fixate_hook_slot,
86         *connection_unlink_hook_slot;
87     pa_time_event *save_time_event;
88     pa_database *database;
89
90     pa_native_protocol *protocol;
91     pa_idxset *subscribed;
92
93     pa_bool_t restore_volume:1;
94     pa_bool_t restore_muted:1;
95     pa_bool_t restore_port:1;
96 };
97
98 /* Protocol extention commands */
99 enum {
100     SUBCOMMAND_TEST,
101     SUBCOMMAND_SUBSCRIBE,
102     SUBCOMMAND_EVENT,
103     SUBCOMMAND_READ_SINK_FORMATS_ALL,
104     SUBCOMMAND_READ_SINK_FORMATS,
105     SUBCOMMAND_SAVE_SINK_FORMATS
106 };
107
108
109 #define ENTRY_VERSION 1
110
111 struct entry {
112     uint8_t version;
113     pa_bool_t muted_valid, volume_valid, port_valid;
114     pa_bool_t muted;
115     pa_channel_map channel_map;
116     pa_cvolume volume;
117     char *port;
118     pa_idxset *formats;
119 };
120
121 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
122     struct userdata *u = userdata;
123
124     pa_assert(a);
125     pa_assert(e);
126     pa_assert(u);
127
128     pa_assert(e == u->save_time_event);
129     u->core->mainloop->time_free(u->save_time_event);
130     u->save_time_event = NULL;
131
132     pa_database_sync(u->database);
133     pa_log_info("Synced.");
134 }
135
136 static void trigger_save(struct userdata *u) {
137     if (u->save_time_event)
138         return;
139
140     u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
141 }
142
143 static struct entry* entry_new(pa_bool_t add_pcm_format) {
144     struct entry *r = pa_xnew0(struct entry, 1);
145     r->version = ENTRY_VERSION;
146     r->formats = pa_idxset_new(NULL, NULL);
147     if (add_pcm_format) {
148         pa_format_info *f = pa_format_info_new();
149         f->encoding = PA_ENCODING_PCM;
150         pa_idxset_put(r->formats, f, NULL);
151     }
152     return r;
153 }
154
155 static void entry_free(struct entry* e) {
156     pa_assert(e);
157
158     pa_idxset_free(e->formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
159     pa_xfree(e->port);
160     pa_xfree(e);
161 }
162
163 static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e) {
164     pa_tagstruct *t;
165     pa_datum key, data;
166     pa_bool_t r;
167     uint32_t i;
168     pa_format_info *f;
169     uint8_t n_formats;
170
171     pa_assert(u);
172     pa_assert(name);
173     pa_assert(e);
174
175     n_formats = pa_idxset_size(e->formats);
176     pa_assert(n_formats > 0);
177
178     t = pa_tagstruct_new(NULL, 0);
179     pa_tagstruct_putu8(t, e->version);
180     pa_tagstruct_put_boolean(t, e->volume_valid);
181     pa_tagstruct_put_channel_map(t, &e->channel_map);
182     pa_tagstruct_put_cvolume(t, &e->volume);
183     pa_tagstruct_put_boolean(t, e->muted_valid);
184     pa_tagstruct_put_boolean(t, e->muted);
185     pa_tagstruct_put_boolean(t, e->port_valid);
186     pa_tagstruct_puts(t, e->port);
187     pa_tagstruct_putu8(t, n_formats);
188
189     PA_IDXSET_FOREACH(f, e->formats, i) {
190         pa_tagstruct_put_format_info(t, f);
191     }
192
193     key.data = (char *) name;
194     key.size = strlen(name);
195
196     data.data = (void*)pa_tagstruct_data(t, &data.size);
197
198     r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
199
200     pa_tagstruct_free(t);
201
202     return r;
203 }
204
205 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
206
207 #define LEGACY_ENTRY_VERSION 2
208 static struct entry* legacy_entry_read(struct userdata *u, pa_datum *data) {
209     struct legacy_entry {
210         uint8_t version;
211         pa_bool_t muted_valid:1, volume_valid:1, port_valid:1;
212         pa_bool_t muted:1;
213         pa_channel_map channel_map;
214         pa_cvolume volume;
215         char port[PA_NAME_MAX];
216     } PA_GCC_PACKED;
217     struct legacy_entry *le;
218     struct entry *e;
219
220     pa_assert(u);
221     pa_assert(data);
222
223     if (data->size != sizeof(struct legacy_entry)) {
224         pa_log_debug("Size does not match.");
225         return NULL;
226     }
227
228     le = (struct legacy_entry*)data->data;
229
230     if (le->version != LEGACY_ENTRY_VERSION) {
231         pa_log_debug("Version mismatch.");
232         return NULL;
233     }
234
235     if (!memchr(le->port, 0, sizeof(le->port))) {
236         pa_log_warn("Port has missing NUL byte.");
237         return NULL;
238     }
239
240     if (le->volume_valid && !pa_channel_map_valid(&le->channel_map)) {
241         pa_log_warn("Invalid channel map.");
242         return NULL;
243     }
244
245     if (le->volume_valid && (!pa_cvolume_valid(&le->volume) || !pa_cvolume_compatible_with_channel_map(&le->volume, &le->channel_map))) {
246         pa_log_warn("Volume and channel map don't match.");
247         return NULL;
248     }
249
250     e = entry_new(TRUE);
251     e->muted_valid = le->muted_valid;
252     e->volume_valid = le->volume_valid;
253     e->port_valid = le->port_valid;
254     e->muted = le->muted;
255     e->channel_map = le->channel_map;
256     e->volume = le->volume;
257     e->port = pa_xstrdup(le->port);
258     return e;
259 }
260 #endif
261
262 static struct entry* entry_read(struct userdata *u, const char *name) {
263     pa_datum key, data;
264     struct entry *e = NULL;
265     pa_tagstruct *t = NULL;
266     const char* port;
267     uint8_t i, n_formats;
268
269     pa_assert(u);
270     pa_assert(name);
271
272     key.data = (char*) name;
273     key.size = strlen(name);
274
275     pa_zero(data);
276
277     if (!pa_database_get(u->database, &key, &data))
278         goto fail;
279
280     t = pa_tagstruct_new(data.data, data.size);
281     e = entry_new(FALSE);
282
283     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
284         e->version > ENTRY_VERSION ||
285         pa_tagstruct_get_boolean(t, &e->volume_valid) < 0 ||
286         pa_tagstruct_get_channel_map(t, &e->channel_map) < 0 ||
287         pa_tagstruct_get_cvolume(t, &e->volume) < 0 ||
288         pa_tagstruct_get_boolean(t, &e->muted_valid) < 0 ||
289         pa_tagstruct_get_boolean(t, &e->muted) < 0 ||
290         pa_tagstruct_get_boolean(t, &e->port_valid) < 0 ||
291         pa_tagstruct_gets(t, &port) < 0 ||
292         pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
293
294         goto fail;
295     }
296
297     e->port = pa_xstrdup(port);
298
299     for (i = 0; i < n_formats; ++i) {
300         pa_format_info *f = pa_format_info_new();
301         if (pa_tagstruct_get_format_info(t, f) < 0) {
302             pa_format_info_free(f);
303             goto fail;
304         }
305         pa_idxset_put(e->formats, f, NULL);
306     }
307
308     if (!pa_tagstruct_eof(t))
309         goto fail;
310
311     if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
312         pa_log_warn("Invalid channel map stored in database for device %s", name);
313         goto fail;
314     }
315
316     if (e->volume_valid && (!pa_cvolume_valid(&e->volume) || !pa_cvolume_compatible_with_channel_map(&e->volume, &e->channel_map))) {
317         pa_log_warn("Volume and channel map don't match in database entry for device %s", name);
318         goto fail;
319     }
320
321     pa_tagstruct_free(t);
322     pa_datum_free(&data);
323
324     return e;
325
326 fail:
327
328     pa_log_debug("Database contains invalid data for key: %s (probably pre-v1.0 data)", name);
329
330     if (e)
331         entry_free(e);
332     if (t)
333         pa_tagstruct_free(t);
334
335 #ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
336     pa_log_debug("Attempting to load legacy (pre-v1.0) data for key: %s", name);
337     if ((e = legacy_entry_read(u, &data))) {
338         pa_log_debug("Success. Saving new format for key: %s", name);
339         if (entry_write(u, name, e))
340             trigger_save(u);
341         pa_datum_free(&data);
342         return e;
343     } else
344         pa_log_debug("Unable to load legacy (pre-v1.0) data for key: %s. Ignoring.", name);
345 #endif
346
347     pa_datum_free(&data);
348     return NULL;
349 }
350
351 static struct entry* entry_copy(const struct entry *e) {
352     struct entry* r;
353     uint32_t idx;
354     pa_format_info *f;
355
356     pa_assert(e);
357     r = entry_new(FALSE);
358     r->version = e->version;
359     r->muted_valid = e->muted_valid;
360     r->volume_valid = e->volume_valid;
361     r->port_valid = e->port_valid;
362     r->muted = e->muted;
363     r->channel_map = e->channel_map;
364     r->volume = e->volume;
365     r->port = pa_xstrdup(e->port);
366
367     PA_IDXSET_FOREACH(f, e->formats, idx) {
368         pa_idxset_put(r->formats, pa_format_info_copy(f), NULL);
369     }
370     return r;
371 }
372
373 static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
374     pa_cvolume t;
375
376     if (a->port_valid != b->port_valid ||
377         (a->port_valid && !pa_streq(a->port, b->port)))
378         return FALSE;
379
380     if (a->muted_valid != b->muted_valid ||
381         (a->muted_valid && (a->muted != b->muted)))
382         return FALSE;
383
384     t = b->volume;
385     if (a->volume_valid != b->volume_valid ||
386         (a->volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->volume)))
387         return FALSE;
388
389     if (pa_idxset_size(a->formats) != pa_idxset_size(b->formats))
390         return FALSE;
391
392     /** TODO: Compare a bit better */
393
394     return TRUE;
395 }
396
397 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
398     struct userdata *u = userdata;
399     struct entry *entry, *old;
400     char *name;
401
402     pa_assert(c);
403     pa_assert(u);
404
405     if (t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW) &&
406         t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE) &&
407         t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW) &&
408         t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE))
409         return;
410
411     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) {
412         pa_sink *sink;
413
414         if (!(sink = pa_idxset_get_by_index(c->sinks, idx)))
415             return;
416
417         name = pa_sprintf_malloc("sink:%s", sink->name);
418
419         if ((old = entry_read(u, name)))
420             entry = entry_copy(old);
421         else
422             entry = entry_new(TRUE);
423
424         if (sink->save_volume) {
425             entry->channel_map = sink->channel_map;
426             entry->volume = *pa_sink_get_volume(sink, FALSE);
427             entry->volume_valid = TRUE;
428         }
429
430         if (sink->save_muted) {
431             entry->muted = pa_sink_get_mute(sink, FALSE);
432             entry->muted_valid = TRUE;
433         }
434
435         if (sink->save_port) {
436             pa_xfree(entry->port);
437             entry->port = pa_xstrdup(sink->active_port ? sink->active_port->name : "");
438             entry->port_valid = TRUE;
439         }
440
441     } else {
442         pa_source *source;
443
444         pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
445
446         if (!(source = pa_idxset_get_by_index(c->sources, idx)))
447             return;
448
449         name = pa_sprintf_malloc("source:%s", source->name);
450
451         if ((old = entry_read(u, name)))
452             entry = entry_copy(old);
453         else
454             entry = entry_new(TRUE);
455
456         if (source->save_volume) {
457             entry->channel_map = source->channel_map;
458             entry->volume = *pa_source_get_volume(source, FALSE);
459             entry->volume_valid = TRUE;
460         }
461
462         if (source->save_muted) {
463             entry->muted = pa_source_get_mute(source, FALSE);
464             entry->muted_valid = TRUE;
465         }
466
467         if (source->save_port) {
468             pa_xfree(entry->port);
469             entry->port = pa_xstrdup(source->active_port ? source->active_port->name : "");
470             entry->port_valid = TRUE;
471         }
472     }
473
474     pa_assert(entry);
475
476     if (old) {
477
478         if (entries_equal(old, entry)) {
479             entry_free(old);
480             entry_free(entry);
481             pa_xfree(name);
482             return;
483         }
484
485         entry_free(old);
486     }
487
488     pa_log_info("Storing volume/mute/port for device %s.", name);
489
490     if (entry_write(u, name, entry))
491         trigger_save(u);
492
493     entry_free(entry);
494     pa_xfree(name);
495 }
496
497 static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
498     char *name;
499     struct entry *e;
500
501     pa_assert(c);
502     pa_assert(new_data);
503     pa_assert(u);
504     pa_assert(u->restore_port);
505
506     name = pa_sprintf_malloc("sink:%s", new_data->name);
507
508     if ((e = entry_read(u, name))) {
509
510         if (e->port_valid) {
511             if (!new_data->active_port) {
512                 pa_log_info("Restoring port for sink %s.", name);
513                 pa_sink_new_data_set_port(new_data, e->port);
514                 new_data->save_port = TRUE;
515             } else
516                 pa_log_debug("Not restoring port for sink %s, because already set.", name);
517         }
518
519         entry_free(e);
520     }
521
522     pa_xfree(name);
523
524     return PA_HOOK_OK;
525 }
526
527 static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
528     char *name;
529     struct entry *e;
530
531     pa_assert(c);
532     pa_assert(new_data);
533     pa_assert(u);
534     pa_assert(u->restore_volume || u->restore_muted);
535
536     name = pa_sprintf_malloc("sink:%s", new_data->name);
537
538     if ((e = entry_read(u, name))) {
539
540         if (u->restore_volume && e->volume_valid) {
541
542             if (!new_data->volume_is_set) {
543                 pa_cvolume v;
544
545                 pa_log_info("Restoring volume for sink %s.", new_data->name);
546
547                 v = e->volume;
548                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
549                 pa_sink_new_data_set_volume(new_data, &v);
550
551                 new_data->save_volume = TRUE;
552             } else
553                 pa_log_debug("Not restoring volume for sink %s, because already set.", new_data->name);
554         }
555
556         if (u->restore_muted && e->muted_valid) {
557
558             if (!new_data->muted_is_set) {
559                 pa_log_info("Restoring mute state for sink %s.", new_data->name);
560                 pa_sink_new_data_set_muted(new_data, e->muted);
561                 new_data->save_muted = TRUE;
562             } else
563                 pa_log_debug("Not restoring mute state for sink %s, because already set.", new_data->name);
564         }
565
566         entry_free(e);
567     }
568
569     pa_xfree(name);
570
571     return PA_HOOK_OK;
572 }
573
574 static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
575     char *name;
576     struct entry *e;
577
578     pa_assert(c);
579     pa_assert(new_data);
580     pa_assert(u);
581     pa_assert(u->restore_port);
582
583     name = pa_sprintf_malloc("source:%s", new_data->name);
584
585     if ((e = entry_read(u, name))) {
586
587         if (e->port_valid) {
588             if (!new_data->active_port) {
589                 pa_log_info("Restoring port for source %s.", name);
590                 pa_source_new_data_set_port(new_data, e->port);
591                 new_data->save_port = TRUE;
592             } else
593                 pa_log_debug("Not restoring port for source %s, because already set.", name);
594         }
595
596         entry_free(e);
597     }
598
599     pa_xfree(name);
600
601     return PA_HOOK_OK;
602 }
603
604 static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
605     char *name;
606     struct entry *e;
607
608     pa_assert(c);
609     pa_assert(new_data);
610     pa_assert(u);
611     pa_assert(u->restore_volume || u->restore_muted);
612
613     name = pa_sprintf_malloc("source:%s", new_data->name);
614
615     if ((e = entry_read(u, name))) {
616
617         if (u->restore_volume && e->volume_valid) {
618
619             if (!new_data->volume_is_set) {
620                 pa_cvolume v;
621
622                 pa_log_info("Restoring volume for source %s.", new_data->name);
623
624                 v = e->volume;
625                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
626                 pa_source_new_data_set_volume(new_data, &v);
627
628                 new_data->save_volume = TRUE;
629             } else
630                 pa_log_debug("Not restoring volume for source %s, because already set.", new_data->name);
631         }
632
633         if (u->restore_muted && e->muted_valid) {
634
635             if (!new_data->muted_is_set) {
636                 pa_log_info("Restoring mute state for source %s.", new_data->name);
637                 pa_source_new_data_set_muted(new_data, e->muted);
638                 new_data->save_muted = TRUE;
639             } else
640                 pa_log_debug("Not restoring mute state for source %s, because already set.", new_data->name);
641         }
642
643         entry_free(e);
644     }
645
646     pa_xfree(name);
647
648     return PA_HOOK_OK;
649 }
650
651 #define EXT_VERSION 1
652
653 static void read_sink_format_reply(struct userdata *u, pa_tagstruct *reply, pa_sink *sink) {
654     struct entry *e;
655     char *name;
656
657     pa_assert(u);
658     pa_assert(reply);
659     pa_assert(sink);
660
661     pa_tagstruct_putu32(reply, sink->index);
662
663     /* Read or create an entry */
664     name = pa_sprintf_malloc("sink:%s", sink->name);
665     if (!(e = entry_read(u, name))) {
666         /* Fake a reply with PCM encoding supported */
667         pa_format_info *f = pa_format_info_new();
668
669         pa_tagstruct_putu8(reply, 1);
670         f->encoding = PA_ENCODING_PCM;
671         pa_tagstruct_put_format_info(reply, f);
672
673         pa_format_info_free(f);
674     } else {
675         uint32_t idx;
676         pa_format_info *f;
677
678         /* Write all the formats from the entry to the reply */
679         pa_tagstruct_putu8(reply, pa_idxset_size(e->formats));
680         PA_IDXSET_FOREACH(f, e->formats, idx) {
681             pa_tagstruct_put_format_info(reply, f);
682         }
683     }
684     pa_xfree(name);
685 }
686
687 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
688     struct userdata *u;
689     uint32_t command;
690     pa_tagstruct *reply = NULL;
691
692     pa_assert(p);
693     pa_assert(m);
694     pa_assert(c);
695     pa_assert(t);
696
697     u = m->userdata;
698
699     if (pa_tagstruct_getu32(t, &command) < 0)
700         goto fail;
701
702     reply = pa_tagstruct_new(NULL, 0);
703     pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
704     pa_tagstruct_putu32(reply, tag);
705
706     switch (command) {
707         case SUBCOMMAND_TEST: {
708             if (!pa_tagstruct_eof(t))
709                 goto fail;
710
711             pa_tagstruct_putu32(reply, EXT_VERSION);
712             break;
713         }
714
715         case SUBCOMMAND_SUBSCRIBE: {
716
717             pa_bool_t enabled;
718
719             if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
720                 !pa_tagstruct_eof(t))
721                 goto fail;
722
723             if (enabled)
724                 pa_idxset_put(u->subscribed, c, NULL);
725             else
726                 pa_idxset_remove_by_data(u->subscribed, c, NULL);
727
728             break;
729         }
730
731         case SUBCOMMAND_READ_SINK_FORMATS_ALL: {
732             pa_sink *sink;
733             uint32_t idx;
734
735             if (!pa_tagstruct_eof(t))
736                 goto fail;
737
738             PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
739                 read_sink_format_reply(u, reply, sink);
740             }
741
742             break;
743         }
744         case SUBCOMMAND_READ_SINK_FORMATS: {
745             uint32_t sink_index;
746             pa_sink *sink;
747
748             pa_assert(reply);
749
750             /* Get the sink index and the number of formats from the tagstruct */
751             if (pa_tagstruct_getu32(t, &sink_index) < 0)
752                 goto fail;
753
754             if (!pa_tagstruct_eof(t))
755                 goto fail;
756
757             /* Now find our sink */
758             if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index)))
759                 goto fail;
760
761             read_sink_format_reply(u, reply, sink);
762
763             break;
764         }
765
766         case SUBCOMMAND_SAVE_SINK_FORMATS: {
767
768             struct entry *e;
769             uint32_t sink_index;
770             char *name;
771             pa_sink *sink;
772             uint8_t i, n_formats;
773
774             /* Get the sink index and the number of formats from the tagstruct */
775             if (pa_tagstruct_getu32(t, &sink_index) < 0 ||
776                 pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
777
778                 goto fail;
779             }
780
781             /* Now find our sink */
782             if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index)))
783                 goto fail;
784
785             /* Read or create an entry */
786             name = pa_sprintf_malloc("sink:%s", sink->name);
787             if (!(e = entry_read(u, name)))
788                 e = entry_new(FALSE);
789
790             /* Read all the formats from our tagstruct */
791             for (i = 0; i < n_formats; ++i) {
792                 pa_format_info *f = pa_format_info_new();
793                 if (pa_tagstruct_get_format_info(t, f) < 0) {
794                     pa_format_info_free(f);
795                     pa_xfree(name);
796                     goto fail;
797                 }
798                 pa_idxset_put(e->formats, f, NULL);
799             }
800
801             if (!pa_tagstruct_eof(t)) {
802                 entry_free(e);
803                 pa_xfree(name);
804                 goto fail;
805             }
806
807             if (entry_write(u, name, e))
808                 trigger_save(u);
809             else
810                 pa_log_warn("Could not save format info for sink %s", sink->name);
811
812             pa_xfree(name);
813             entry_free(e);
814
815             break;
816         }
817
818         default:
819             goto fail;
820     }
821
822     pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
823     return 0;
824
825 fail:
826
827     if (reply)
828         pa_tagstruct_free(reply);
829
830     return -1;
831 }
832
833 static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
834     pa_assert(p);
835     pa_assert(c);
836     pa_assert(u);
837
838     pa_idxset_remove_by_data(u->subscribed, c, NULL);
839     return PA_HOOK_OK;
840 }
841
842 int pa__init(pa_module*m) {
843     pa_modargs *ma = NULL;
844     struct userdata *u;
845     char *fname;
846     pa_sink *sink;
847     pa_source *source;
848     uint32_t idx;
849     pa_bool_t restore_volume = TRUE, restore_muted = TRUE, restore_port = TRUE;
850
851     pa_assert(m);
852
853     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
854         pa_log("Failed to parse module arguments");
855         goto fail;
856     }
857
858     if (pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
859         pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
860         pa_modargs_get_value_boolean(ma, "restore_port", &restore_port) < 0) {
861         pa_log("restore_port=, restore_volume= and restore_muted= expect boolean arguments");
862         goto fail;
863     }
864
865     if (!restore_muted && !restore_volume && !restore_port)
866         pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring port enabled!");
867
868     m->userdata = u = pa_xnew0(struct userdata, 1);
869     u->core = m->core;
870     u->module = m;
871     u->restore_volume = restore_volume;
872     u->restore_muted = restore_muted;
873     u->restore_port = restore_port;
874
875     u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
876
877     u->protocol = pa_native_protocol_get(m->core);
878     pa_native_protocol_install_ext(u->protocol, m, extension_cb);
879
880     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);
881
882     u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE, subscribe_callback, u);
883
884     if (restore_port) {
885         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);
886         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);
887     }
888
889     if (restore_muted || restore_volume) {
890         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);
891         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);
892     }
893
894     if (!(fname = pa_state_path("device-volumes", TRUE)))
895         goto fail;
896
897     if (!(u->database = pa_database_open(fname, TRUE))) {
898         pa_log("Failed to open volume database '%s': %s", fname, pa_cstrerror(errno));
899         pa_xfree(fname);
900         goto fail;
901     }
902
903     pa_log_info("Successfully opened database file '%s'.", fname);
904     pa_xfree(fname);
905
906     for (sink = pa_idxset_first(m->core->sinks, &idx); sink; sink = pa_idxset_next(m->core->sinks, &idx))
907         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);
908
909     for (source = pa_idxset_first(m->core->sources, &idx); source; source = pa_idxset_next(m->core->sources, &idx))
910         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, source->index, u);
911
912     pa_modargs_free(ma);
913     return 0;
914
915 fail:
916     pa__done(m);
917
918     if (ma)
919         pa_modargs_free(ma);
920
921     return -1;
922 }
923
924 void pa__done(pa_module*m) {
925     struct userdata* u;
926
927     pa_assert(m);
928
929     if (!(u = m->userdata))
930         return;
931
932     if (u->subscription)
933         pa_subscription_free(u->subscription);
934
935     if (u->sink_fixate_hook_slot)
936         pa_hook_slot_free(u->sink_fixate_hook_slot);
937     if (u->source_fixate_hook_slot)
938         pa_hook_slot_free(u->source_fixate_hook_slot);
939     if (u->sink_new_hook_slot)
940         pa_hook_slot_free(u->sink_new_hook_slot);
941     if (u->source_new_hook_slot)
942         pa_hook_slot_free(u->source_new_hook_slot);
943
944     if (u->connection_unlink_hook_slot)
945         pa_hook_slot_free(u->connection_unlink_hook_slot);
946
947     if (u->save_time_event)
948         u->core->mainloop->time_free(u->save_time_event);
949
950     if (u->database)
951         pa_database_close(u->database);
952
953     if (u->protocol) {
954         pa_native_protocol_remove_ext(u->protocol, m);
955         pa_native_protocol_unref(u->protocol);
956     }
957
958     if (u->subscribed)
959         pa_idxset_free(u->subscribed, NULL, NULL);
960
961     pa_xfree(u);
962 }