bluez5: retain volume level when changing between sw/hw volume

Add logic for retaining volume level when switching between HW and SW
volume control.

This avoids large volume level changes, when hardware volume control
becomes disabled or enabled.

This can be tested by a BlueZ patch that makes volume presence
toggleable,

```diff
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index d158fc97a..5fa3ce030 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -102,6 +102,7 @@ struct media_transport {
 };

 static GSList *transports = NULL;
+static bool volume_disabled;

 static const char *state2str(transport_state_t state)
 {
@@ -535,6 +536,14 @@ static DBusMessage *release(DBusConnection *conn, DBusMessage *msg,
        return NULL;
 }

+static DBusMessage *toggle_volume(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+       struct media_transport *transport = data;
+       volume_disabled = !volume_disabled;
+       g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path, MEDIA_TRANSPORT_INTERFACE, "Volume");
+       return btd_error_in_progress(msg);
+}
+
 static gboolean get_device(const GDBusPropertyTable *property,
                                        DBusMessageIter *iter, void *data)
 {
@@ -621,7 +630,7 @@ static gboolean volume_exists(const GDBusPropertyTable *property, void *data)
        struct media_transport *transport = data;
        struct a2dp_transport *a2dp = transport->data;

-       return a2dp->volume >= 0;
+       return a2dp->volume >= 0 && !volume_disabled;
 }

 static gboolean get_volume(const GDBusPropertyTable *property,
@@ -706,6 +715,7 @@ static const GDBusMethodTable transport_methods[] = {
                                                        { "mtu_w", "q" }),
                        try_acquire) },
        { GDBUS_ASYNC_METHOD("Release", NULL, NULL, release) },
+       { GDBUS_ASYNC_METHOD("ToggleVolume", NULL, NULL, toggle_volume) },
        { },
 };
```
32 jobs for bt-hw-volume-away in 8 minutes and 28 seconds (queued for 8 seconds)
latest
Status Name Job ID Coverage
  Container
passed container_fedora #14568081

00:00:21

passed container_ubuntu #14568080

00:00:22

 
  Build
passed build_on_fedora #14568083

00:01:30

passed build_on_ubuntu #14568082

00:01:16

passed build_release #14568107

00:00:32

passed build_with_custom_options: [audiotestsrc, disabled] #14568094

00:01:36

passed build_with_custom_options: [audiotestsrc, enabled] #14568093

00:01:37

passed build_with_custom_options: [bluez5-backend-hsphfpd, disabled] #14568092

00:01:37

passed build_with_custom_options: [bluez5-backend-hsphfpd, enabled] #14568091

00:01:33

passed build_with_custom_options: [docs, disabled] #14568086

00:01:21

passed build_with_custom_options: [docs, enabled] #14568085

00:01:23

passed build_with_custom_options: [installed_tests, disabled] #14568088

00:01:14

passed build_with_custom_options: [installed_tests, enabled] #14568087

00:01:14

passed build_with_custom_options: [sdl2, disabled] #14568104

00:00:26

passed build_with_custom_options: [sdl2, enabled] #14568103

00:00:26

passed build_with_custom_options: [sndfile, disabled] #14568106

00:00:43

passed build_with_custom_options: [sndfile, enabled] #14568105

00:00:27

passed build_with_custom_options: [systemd-system-service, disabled] #14568090

00:01:14

passed build_with_custom_options: [systemd-system-service, enabled] #14568089

00:01:13

passed build_with_custom_options: [test, disabled] #14568096

00:01:10

passed build_with_custom_options: [test, enabled] #14568095

00:01:01

passed build_with_custom_options: [videotestsrc, disabled] #14568098

00:00:27

passed build_with_custom_options: [videotestsrc, enabled] #14568097

00:01:10

passed build_with_custom_options: [volume, disabled] #14568100

00:01:14

passed build_with_custom_options: [volume, enabled] #14568099

00:01:14

passed build_with_custom_options: [vulkan, disabled] #14568102

00:01:24

passed build_with_custom_options: [vulkan, enabled] #14568101

00:01:19

passed build_with_no_commandline_options #14568084

00:01:23

failed valgrind #14568108

00:05:28

 
  Analysis
skipped doccheck #14568111
skipped shellcheck #14568109
skipped spellcheck #14568110
 
Name Stage Failure
failed
valgrind Build
Timeout:            0   

Full log written to /builds/pvir/pipewire/build-14568108/meson-logs/testlog-valgrind.txt
Uploading artifacts for failed job
Uploading artifacts...
build-*/meson-logs: found 5 matching files and directories

Uploading artifacts as "archive" to coordinator... ok
id=14568108 responseStatus=201 Created token=5j7jyvTU
Cleaning up file based variables
ERROR: Job failed: exit code 1