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

Commit d389c910 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
Change-Id: Ia935b3644e5909c88457190f975ec1a01180a1fc
parent d8ab42c8
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -760,6 +760,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
    void onAudioModeChanged() {
    void onAudioModeChanged() {
        dispatchAttributesChanged();
        dispatchAttributesChanged();
    }
    }

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

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


package com.android.server.audio;
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 static android.media.AudioSystem.isBluetoothDevice;


import android.annotation.NonNull;
import android.annotation.NonNull;
@@ -682,8 +684,20 @@ public class SpatializerHelper {
            Log.i(TAG, "no spatialization device state found for Spatial Audio device:" + ada);
            Log.i(TAG, "no spatialization device state found for Spatial Audio device:" + ada);
            return new Pair<>(false, false);
            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.
        // 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) {
    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) {
    synchronized boolean isAvailableForDevice(@NonNull AudioDeviceAttributes ada) {
        if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
        if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
            return false;
            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,
    private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes,