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

Commit f9bd2e6b authored by Vlad Popa's avatar Vlad Popa
Browse files

Change spatializer availability based on audio category

Introduce change of audio device category. Cached BT devices should
notify that a new audio device category was selected.

Test: manual
Bug: 297265575
Merged-In: Ia935b3644e5909c88457190f975ec1a01180a1fc
Change-Id: Ia935b3644e5909c88457190f975ec1a01180a1fc
parent 3f6b43cf
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -728,6 +728,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
    void onAudioModeChanged() {
        dispatchAttributesChanged();
    }

    /**
     * Notify that the audio category has changed.
     */
    public void onAudioDeviceCategoryChanged() {
        dispatchAttributesChanged();
    }

    /**
     * Get the device status as active or non-active per Bluetooth profile.
     *
+1 −0
Original line number Diff line number Diff line
@@ -10743,6 +10743,7 @@ public class AudioService extends IAudioService.Stub
        mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
        mDeviceBroker.persistAudioDeviceSettings();
        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
        mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
                btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
    }
+41 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.audio;

import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
import static android.media.AudioSystem.isBluetoothDevice;

import android.annotation.NonNull;
@@ -682,8 +684,20 @@ public class SpatializerHelper {
            Log.i(TAG, "no spatialization device state found for Spatial Audio device:" + ada);
            return new Pair<>(false, false);
        }
        boolean available = true;
        if (isBluetoothDevice(deviceType)) {
            // only checking headphones/binaural because external speakers cannot use transaural
            // since their physical characteristics are unknown
            if (deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_UNKNOWN
                    || deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES) {
                available = (spatMode == SpatializationMode.SPATIALIZER_BINAURAL)
                        && mBinauralSupported;
            } else {
                available = false;
            }
        }
        // found the matching device state.
        return new Pair<>(deviceState.isSAEnabled(), true /* available */);
        return new Pair<>(deviceState.isSAEnabled(), available);
    }

    private synchronized void addWirelessDeviceIfNew(@NonNull AudioDeviceAttributes ada) {
@@ -740,11 +754,36 @@ public class SpatializerHelper {
        }
    }

    synchronized void refreshDevice(@NonNull AudioDeviceAttributes ada) {
        final AdiDeviceState deviceState = findSACompatibleDeviceStateForAudioDeviceAttributes(ada);
        if (isAvailableForAdiDeviceState(deviceState)) {
            addCompatibleAudioDevice(ada, /*forceEnable=*/deviceState.isSAEnabled());
            setHeadTrackerEnabled(deviceState.isHeadTrackerEnabled(), ada);
        } else {
            removeCompatibleAudioDevice(ada);
        }
    }

    synchronized boolean isAvailableForDevice(@NonNull AudioDeviceAttributes ada) {
        if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
            return false;
        }
        return findSACompatibleDeviceStateForAudioDeviceAttributes(ada) != null;

        return isAvailableForAdiDeviceState(
                findSACompatibleDeviceStateForAudioDeviceAttributes(ada));
    }

    private boolean isAvailableForAdiDeviceState(AdiDeviceState deviceState) {
        if (deviceState == null) {
            return false;
        }

        if (isBluetoothDevice(deviceState.getInternalDeviceType())
                && deviceState.getAudioDeviceCategory() != AUDIO_DEVICE_CATEGORY_UNKNOWN
                && deviceState.getAudioDeviceCategory() != AUDIO_DEVICE_CATEGORY_HEADPHONES) {
            return false;
        }
        return true;
    }

    private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes,