stream-restore: Forget pre-14.0 stream routing
authorTanu Kaskinen <tanuk@iki.fi>
Tue, 26 May 2020 12:04:59 +0000 (15:04 +0300)
committerGeorg Chini <georg@chini.tk>
Mon, 1 Jun 2020 18:24:16 +0000 (18:24 +0000)
Prior to commits f899d5f4669dcd536cc142cee99fe359dd8af3d6 and
f62a49b8cf109c011a9818d2358beb6834e6ec25, GNOME's sound settings
overwrote the routing for all entries in the stream-restore database
when selecting a device. Now we prevent that from happening (see the
aforementioned commits), but the old overwritten settings can still be in
the database after updating to PulseAudio 14.0, and they can cause
problems, as documented here:
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832

We can't distinguish between devices set by GNOME's sound settings
and devices set by the user, so this patch discards all old device
settings, even though that is going to cause PulseAudio to forget routing
settings for many users. This is less bad than keeping the incorrect
routing settings in the database, because it's difficult for users to
figure out how to fix the situation when e.g. speaker test tones go to
the internal speakers no matter what device is selected as the default,
whereas old manual configuration can be restored restored by doing the
manual configuration again. Also, it's probably more common to have at
some point changed the default device in GNOME's sound settings than it
is to have any manual per-stream routing settings.

This is disabled by default, because this causes data loss, but
distributions that use GNOME are recommended to enable this with
the --enable-stream-restore-clear-old-devices (Autotools) or
-Dstream-restore-clear-old-devices=true (Meson) build option.

Fixes: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832

configure.ac
meson.build
meson_options.txt
src/modules/module-stream-restore.c

index fa93172..11142cd 100644 (file)
@@ -1477,6 +1477,12 @@ if test "x$enable_legacy_database_entry_format" != "xno" ; then
         AC_DEFINE(ENABLE_LEGACY_DATABASE_ENTRY_FORMAT, [1], [Legacy database entry format])
 fi
 
+AC_ARG_ENABLE([stream-restore-clear-old-devices],
+    AS_HELP_STRING([--enable-stream-restore-clear-old-devices], [Forget per-stream routing settings that have been set before version 14.0. Recommended when using GNOME. See https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832]))
+if test "x$enable_stream_restore_clear_old_devices" == "xyes" ; then
+    AC_DEFINE(STREAM_RESTORE_CLEAR_OLD_DEVICES, [1], [module-stream-restore: Clear old devices])
+fi
+
 AC_ARG_ENABLE([static-bins],
     AS_HELP_STRING([--enable-static-bins],[Statically link executables.]))
 AM_CONDITIONAL([STATIC_BINS], [test "x$enable_static_bins" = "xyes"])
@@ -1639,6 +1645,7 @@ AS_IF([test "x$HAVE_ESOUND" = "x1" -a "x$USE_PER_USER_ESOUND_SOCKET" = "x1"], EN
 AS_IF([test "x$HAVE_GCOV" = "x1"], ENABLE_GCOV=yes, ENABLE_GCOV=no)
 AS_IF([test "x$HAVE_LIBCHECK" = "x1"], ENABLE_TESTS=yes, ENABLE_TESTS=no)
 AS_IF([test "x$enable_legacy_database_entry_format" != "xno"], ENABLE_LEGACY_DATABASE_ENTRY_FORMAT=yes, ENABLE_LEGACY_DATABASE_ENTRY_FORMAT=no)
+AS_IF([test "x$enable_stream_restore_clear_old_devices" == "xyes"], ENABLE_STREAM_RESTORE_CLEAR_OLD_DEVICES=yes, ENABLE_STREAM_RESTORE_CLEAR_OLD_DEVICES=no)
 
 echo "
  ---{ $PACKAGE_NAME $VERSION }---
@@ -1710,6 +1717,8 @@ echo "
     Preopened modules:             ${PREOPEN_MODS}
 
     Legacy Database Entry Support: ${ENABLE_LEGACY_DATABASE_ENTRY_FORMAT}
+    module-stream-restore:
+      Clear old devices:           ${ENABLE_STREAM_RESTORE_CLEAR_OLD_DEVICES}
 "
 
 if test "${ENABLE_SPEEX}" = "no" && test "${ENABLE_WEBRTC}" = "no" && test "${ENABLE_ADRIAN_EC}" = "no" ; then
index 88394e4..abb0ba2 100644 (file)
@@ -522,6 +522,10 @@ if get_option('legacy-database-entry-format')
   cdata.set('ENABLE_LEGACY_DATABASE_ENTRY_FORMAT', 1)
 endif
 
+if get_option('stream-restore-clear-old-devices')
+  cdata.set('STREAM_RESTORE_CLEAR_OLD_DEVICES', 1)
+endif
+
 if get_option('running-from-build-tree')
   cdata.set('HAVE_RUNNING_FROM_BUILD_TREE', 1)
 endif
@@ -835,6 +839,8 @@ summary = [
   '',
   'Database:                      @0@'.format(get_option('database')),
   'Legacy Database Entry Support: @0@'.format(get_option('legacy-database-entry-format')),
+  'module-stream-restore:',
+  '  Clear old devices:           @0@'.format(get_option('stream-restore-clear-old-devices')),
   'Running from build tree:       @0@'.format(get_option('running-from-build-tree')),
   'System User:                   @0@'.format(cdata.get_unquoted('PA_SYSTEM_USER')),
   'System Group:                  @0@'.format(cdata.get_unquoted('PA_SYSTEM_GROUP')),
index 8178892..c11b67e 100644 (file)
@@ -24,6 +24,9 @@ option('database',
 option('legacy-database-entry-format',
        type : 'boolean',
        description : 'Try to load legacy (< 1.0) database files (card, device and volume restore)')
+option('stream-restore-clear-old-devices',
+       type : 'boolean', value : false,
+       description : 'Forget per-stream routing settings that have been set before version 14.0. Recommended when using GNOME. See https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832')
 option('running-from-build-tree',
        type : 'boolean',
        description : 'Enable running from build tree')
index a86e6bc..a3c7671 100644 (file)
@@ -113,7 +113,7 @@ struct userdata {
 #endif
 };
 
-#define ENTRY_VERSION 1
+#define ENTRY_VERSION 2
 
 struct entry {
     bool muted_valid, volume_valid, device_valid, card_valid;
@@ -1167,6 +1167,46 @@ static struct entry *entry_read(struct userdata *u, const char *name) {
     pa_tagstruct_free(t);
     pa_datum_free(&data);
 
+#ifdef STREAM_RESTORE_CLEAR_OLD_DEVICES
+    if (version < ENTRY_VERSION && e->device_valid) {
+        /* Prior to PulseAudio 14.0, GNOME's sound settings overwrote the
+         * routing for all entries in the stream-restore database when
+         * selecting a device. PulseAudio 14.0 prevents that from happening,
+         * but the old overwritten settings can still be in the database after
+         * updating to PulseAudio 14.0, and they can cause problems, as
+         * documented here:
+         * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832
+         *
+         * We can't distinguish between devices set by GNOME's sound settings
+         * and devices set by the user, so we discard all old device settings,
+         * even though that is going to cause PulseAudio to forget routing
+         * settings for many users. This is less bad than keeping the incorrect
+         * routing settings in the database, because it's difficult for users
+         * to figure out how to fix the situation when e.g. speaker test tones
+         * go to the internal speakers no matter what device is selected as the
+         * default, whereas old manual configuration can be restored restored
+         * by doing the manual configuration again. Also, it's probably more
+         * common to have at some point changed the default device in GNOME's
+         * sound settings than it is to have any manual per-stream routing
+         * settings. */
+        pa_log_warn("Device set, but it might be incorrect. Clearing the device. If this messes up your manual stream "
+                    "routing configuration, sorry about that. This is a workaround for this bug: "
+                    "https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832");
+        pa_log_warn("%s: device: %s -> (unset)", name, e->device);
+        pa_xfree(e->device);
+        e->device = NULL;
+        e->device_valid = false;
+        if (e->card_valid) {
+            pa_log_warn("%s: card: %s -> (unset)", name, e->card);
+            pa_xfree(e->card);
+            e->card = NULL;
+            e->card_valid = false;
+        }
+        entry_write(u, name, e, true);
+        trigger_save(u);
+    }
+#endif
+
     return e;
 
 fail: