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

Commit 73f19b45 authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioService: fix spatial audio state restoring and head tracker detection

Fix two problems in spatial audio state management:
1) Fix overwriting of restored spatial audio state due to race
condition between SpatializerHelper init() in AudioService handler
and synchronization of device state in inventory in AudioDeviceBroker
handler.
2) Force initialization of Bluetooth device identity address with base
address if the identity address is not returned by the BT stack.

Test: repo steps in bug
Bug: 347602571
Flag: EXEMPT bug fix
Change-Id: I6614d1ea61cd7d0660124ca376ae2d9ce77259d8
parent 1d74a5f2
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -2793,12 +2793,13 @@ public class AudioDeviceBroker {
        return mDeviceInventory.getImmutableDeviceInventory();
        return mDeviceInventory.getImmutableDeviceInventory();
    }
    }


    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState, boolean syncInventory) {
        mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState);
        mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState, syncInventory);
    }
    }


    void addOrUpdateBtAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
    void addOrUpdateBtAudioDeviceCategoryInInventory(
        mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState);
            AdiDeviceState deviceState, boolean syncInventory) {
        mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState, syncInventory);
    }
    }


    @Nullable
    @Nullable
+46 −17
Original line number Original line Diff line number Diff line
@@ -135,9 +135,10 @@ public class AudioDeviceInventory {
     * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
     * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
     * @param deviceState the device to update
     * @param deviceState the device to update
     */
     */
    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState, boolean syncInventory) {
        synchronized (mDeviceInventoryLock) {
        synchronized (mDeviceInventoryLock) {
            mDeviceInventory.merge(deviceState.getDeviceId(), deviceState, (oldState, newState) -> {
            mDeviceInventory.merge(deviceState.getDeviceId(), deviceState,
                    (oldState, newState) -> {
                oldState.setHasHeadTracker(newState.hasHeadTracker());
                oldState.setHasHeadTracker(newState.hasHeadTracker());
                oldState.setHeadTrackerEnabled(newState.isHeadTrackerEnabled());
                oldState.setHeadTrackerEnabled(newState.isHeadTrackerEnabled());
                oldState.setSAEnabled(newState.isSAEnabled());
                oldState.setSAEnabled(newState.isSAEnabled());
@@ -145,8 +146,10 @@ public class AudioDeviceInventory {
            });
            });
            checkDeviceInventorySize_l();
            checkDeviceInventorySize_l();
        }
        }
        if (syncInventory) {
            mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
            mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
        }
        }
    }


    /**
    /**
     * Adds a new entry in mDeviceInventory if the attributes passed represent a sink
     * Adds a new entry in mDeviceInventory if the attributes passed represent a sink
@@ -196,7 +199,8 @@ public class AudioDeviceInventory {
     * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
     * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
     * @param deviceState the device to update
     * @param deviceState the device to update
     */
     */
    void addOrUpdateAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
    void addOrUpdateAudioDeviceCategoryInInventory(
            AdiDeviceState deviceState, boolean syncInventory) {
        AtomicBoolean updatedCategory = new AtomicBoolean(false);
        AtomicBoolean updatedCategory = new AtomicBoolean(false);
        synchronized (mDeviceInventoryLock) {
        synchronized (mDeviceInventoryLock) {
            if (automaticBtDeviceType()) {
            if (automaticBtDeviceType()) {
@@ -218,8 +222,10 @@ public class AudioDeviceInventory {
        if (updatedCategory.get()) {
        if (updatedCategory.get()) {
            mDeviceBroker.postUpdatedAdiDeviceState(deviceState, false /*initSA*/);
            mDeviceBroker.postUpdatedAdiDeviceState(deviceState, false /*initSA*/);
        }
        }
        if (syncInventory) {
            mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
            mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
        }
        }
    }


    void addAudioDeviceWithCategoryInInventoryIfNeeded(@NonNull String address,
    void addAudioDeviceWithCategoryInInventoryIfNeeded(@NonNull String address,
            @AudioDeviceCategory int btAudioDeviceCategory) {
            @AudioDeviceCategory int btAudioDeviceCategory) {
@@ -235,14 +241,14 @@ public class AudioDeviceInventory {
        boolean bleCategoryFound = false;
        boolean bleCategoryFound = false;
        AdiDeviceState deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLE_HEADSET);
        AdiDeviceState deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLE_HEADSET);
        if (deviceState != null) {
        if (deviceState != null) {
            addOrUpdateAudioDeviceCategoryInInventory(deviceState);
            addOrUpdateAudioDeviceCategoryInInventory(deviceState, true /*syncInventory*/);
            btCategory = deviceState.getAudioDeviceCategory();
            btCategory = deviceState.getAudioDeviceCategory();
            bleCategoryFound = true;
            bleCategoryFound = true;
        }
        }


        deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLUETOOTH_A2DP);
        deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLUETOOTH_A2DP);
        if (deviceState != null) {
        if (deviceState != null) {
            addOrUpdateAudioDeviceCategoryInInventory(deviceState);
            addOrUpdateAudioDeviceCategoryInInventory(deviceState, true /*syncInventory*/);
            int a2dpCategory = deviceState.getAudioDeviceCategory();
            int a2dpCategory = deviceState.getAudioDeviceCategory();
            if (bleCategoryFound && a2dpCategory != btCategory) {
            if (bleCategoryFound && a2dpCategory != btCategory) {
                Log.w(TAG, "Found different audio device category for A2DP and BLE profiles with "
                Log.w(TAG, "Found different audio device category for A2DP and BLE profiles with "
@@ -269,11 +275,33 @@ public class AudioDeviceInventory {
    }
    }


    /**
    /**
     * synchronize AdiDeviceState for LE devices in the same group
     * Synchronize AdiDeviceState for LE devices in the same group
     * or BT classic devices with the same address.
     * @param updatedDevice the device state to synchronize or null.
     * Called with null once after the device inventory and spatializer helper
     * have been initialized to resync all devices.
     */
     */
    void onSynchronizeAdiDevicesInInventory(AdiDeviceState updatedDevice) {
    void onSynchronizeAdiDevicesInInventory(AdiDeviceState updatedDevice) {
        synchronized (mDevicesLock) {
        synchronized (mDevicesLock) {
            synchronized (mDeviceInventoryLock) {
            synchronized (mDeviceInventoryLock) {
                if (updatedDevice != null) {
                    onSynchronizeAdiDeviceInInventory_l(updatedDevice);
                } else {
                    for (AdiDeviceState ads : mDeviceInventory.values()) {
                        onSynchronizeAdiDeviceInInventory_l(ads);
                    }
                }
            }
        }
    }

    /**
     * Synchronize AdiDeviceState for LE devices in the same group
     * or BT classic devices with the same address.
     * @param updatedDevice the device state to synchronize.
     */
    @GuardedBy({"mDevicesLock", "mDeviceInventoryLock"})
    void onSynchronizeAdiDeviceInInventory_l(AdiDeviceState updatedDevice) {
        boolean found = false;
        boolean found = false;
        found |= synchronizeBleDeviceInInventory(updatedDevice);
        found |= synchronizeBleDeviceInInventory(updatedDevice);
        if (automaticBtDeviceType()) {
        if (automaticBtDeviceType()) {
@@ -283,8 +311,6 @@ public class AudioDeviceInventory {
            mDeviceBroker.postPersistAudioDeviceSettings();
            mDeviceBroker.postPersistAudioDeviceSettings();
        }
        }
    }
    }
        }
    }


    @GuardedBy("mDeviceInventoryLock")
    @GuardedBy("mDeviceInventoryLock")
    private void checkDeviceInventorySize_l() {
    private void checkDeviceInventorySize_l() {
@@ -595,6 +621,9 @@ public class AudioDeviceInventory {
            mDeviceName = TextUtils.emptyIfNull(deviceName);
            mDeviceName = TextUtils.emptyIfNull(deviceName);
            mDeviceAddress = TextUtils.emptyIfNull(address);
            mDeviceAddress = TextUtils.emptyIfNull(address);
            mDeviceIdentityAddress = TextUtils.emptyIfNull(identityAddress);
            mDeviceIdentityAddress = TextUtils.emptyIfNull(identityAddress);
            if (mDeviceIdentityAddress.isEmpty()) {
                mDeviceIdentityAddress = mDeviceAddress;
            }
            mDeviceCodecFormat = codecFormat;
            mDeviceCodecFormat = codecFormat;
            mGroupId = groupId;
            mGroupId = groupId;
            mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
            mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
@@ -2951,8 +2980,8 @@ public class AudioDeviceInventory {
            // Note if the device is not compatible with spatialization mode or the device
            // Note if the device is not compatible with spatialization mode or the device
            // type is not canonical, it will be ignored in {@link SpatializerHelper}.
            // type is not canonical, it will be ignored in {@link SpatializerHelper}.
            if (devState != null) {
            if (devState != null) {
                addOrUpdateDeviceSAStateInInventory(devState);
                addOrUpdateDeviceSAStateInInventory(devState, false /*syncInventory*/);
                addOrUpdateAudioDeviceCategoryInInventory(devState);
                addOrUpdateAudioDeviceCategoryInInventory(devState, false /*syncInventory*/);
            }
            }
        }
        }
    }
    }
+5 −1
Original line number Original line Diff line number Diff line
@@ -9639,6 +9639,9 @@ public class AudioService extends IAudioService.Stub
                case MSG_INIT_SPATIALIZER:
                case MSG_INIT_SPATIALIZER:
                    onInitSpatializer();
                    onInitSpatializer();
                    // the device inventory can only be synchronized after the
                    // spatializer has been initialized
                    mDeviceBroker.postSynchronizeAdiDevicesInInventory(null);
                    mAudioEventWakeLock.release();
                    mAudioEventWakeLock.release();
                    break;
                    break;
@@ -11394,7 +11397,8 @@ public class AudioService extends IAudioService.Stub
        deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
        deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
        mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
        mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(
                deviceState, true /*syncInventory*/);
        mDeviceBroker.postPersistAudioDeviceSettings();
        mDeviceBroker.postPersistAudioDeviceSettings();
        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
+3 −2
Original line number Original line Diff line number Diff line
@@ -568,7 +568,8 @@ public class SpatializerHelper {
            updatedDevice = new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
            updatedDevice = new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
                    ada.getAddress());
                    ada.getAddress());
            initSAState(updatedDevice);
            initSAState(updatedDevice);
            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(updatedDevice);
            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(
                    updatedDevice, true /*syncInventory*/);
        }
        }
        if (updatedDevice != null) {
        if (updatedDevice != null) {
            onRoutingUpdated();
            onRoutingUpdated();
@@ -723,7 +724,7 @@ public class SpatializerHelper {
                    new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
                    new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
                            ada.getAddress());
                            ada.getAddress());
            initSAState(deviceState);
            initSAState(deviceState);
            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState);
            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState, true /*syncInventory*/);
            mDeviceBroker.postPersistAudioDeviceSettings();
            mDeviceBroker.postPersistAudioDeviceSettings();
            logDeviceState(deviceState, "addWirelessDeviceIfNew"); // may be updated later.
            logDeviceState(deviceState, "addWirelessDeviceIfNew"); // may be updated later.
        }
        }