Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04d23baa authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioDeviceInventory: fix devices role management

AudioDeviceInventory.setDevicesRole() implementation was wrong when
trying to merge devices selection for a given <role|strategy> and also
systematically clearing an existing selection before applying a new one.
setDevicesRoles() is used only for non additive scenario where a set of
devices will replace the existing one if any.
If the desired behavior is to add devices to an existing preference,
then addDevicesRole() should be used.

This causes the unwanted systematic reset of call route to default
when switching from one route to another.

Bug: 307161477
Test: repro steps in the bug
Test: AudioCommunicationDeviceTest
Change-Id: I09dd9a6c4ad2425b2d9a281e17f112789baeef17
parent d2ec9ccb
Loading
Loading
Loading
Loading
+37 −21
Original line number Diff line number Diff line
@@ -1335,6 +1335,27 @@ public class AudioDeviceInventory {
        }
    }

    private static boolean devicesListEqual(@NonNull List<AudioDeviceAttributes> list1,
                                            @NonNull List<AudioDeviceAttributes> list2) {
        if (list1.size() != list2.size()) {
            return false;
        }
        // This assumes a given device is only present once in a list
        for (AudioDeviceAttributes d1 : list1) {
            boolean found = false;
            for (AudioDeviceAttributes d2 : list2) {
                if (d1.equalTypeAddress(d2)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                return false;
            }
        }
        return true;
    }

    private int setDevicesRole(
            ArrayMap<Pair<Integer, Integer>, List<AudioDeviceAttributes>> rolesMap,
            AudioSystemInterface addOp,
@@ -1342,31 +1363,26 @@ public class AudioDeviceInventory {
            int useCase, int role, @NonNull List<AudioDeviceAttributes> devices) {
        synchronized (rolesMap) {
            Pair<Integer, Integer> key = new Pair<>(useCase, role);
            List<AudioDeviceAttributes> roleDevices = new ArrayList<>();
            List<AudioDeviceAttributes> appliedDevices = new ArrayList<>();

            if (rolesMap.containsKey(key)) {
                roleDevices = rolesMap.get(key);
                boolean equal = false;
                if (roleDevices.size() == devices.size()) {
                    roleDevices.retainAll(devices);
                    equal = roleDevices.size() == devices.size();
                }
                if (!equal) {
                    clearOp.deviceRoleAction(useCase, role, null);
                    roleDevices.clear();
                    appliedDevices.addAll(devices);
                }
            } else {
                appliedDevices.addAll(devices);
                if (devicesListEqual(devices, rolesMap.get(key))) {
                    // NO OP: no change in preference
                    return AudioSystem.SUCCESS;
                }
            if (appliedDevices.isEmpty()) {
            } else if (devices.isEmpty()) {
                // NO OP: no preference to no preference
                return AudioSystem.SUCCESS;
            }
            final int status = addOp.deviceRoleAction(useCase, role, appliedDevices);
            int status;
            if (devices.isEmpty()) {
                status = clearOp.deviceRoleAction(useCase, role, null);
                if (status == AudioSystem.SUCCESS) {
                roleDevices.addAll(appliedDevices);
                rolesMap.put(key, roleDevices);
                    rolesMap.remove(key);
                }
            } else {
                status = addOp.deviceRoleAction(useCase, role, devices);
                if (status == AudioSystem.SUCCESS) {
                    rolesMap.put(key, devices);
                }
            }
            return status;
        }