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

Commit d9b50a55 authored by Jack He's avatar Jack He Committed by Automerger Merge Worker
Browse files

Merge "LeAudio: Fix volume issues" am: a8fb0865

parents 25a2ad4f a8fb0865
Loading
Loading
Loading
Loading
+3 −27
Original line number Diff line number Diff line
@@ -34,8 +34,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.HandlerThread;
import android.os.ParcelUuid;
@@ -170,11 +168,6 @@ public class VolumeControlService extends ProfileService {
        Map<Integer, Descriptor> mVolumeOffsets;
    }

    private int mMusicMaxVolume = 0;
    private int mMusicMinVolume = 0;
    private int mVoiceCallMaxVolume = 0;
    private int mVoiceCallMinVolume = 0;

    @VisibleForTesting
    VolumeControlNativeInterface mVolumeControlNativeInterface;
    @VisibleForTesting
@@ -228,11 +221,6 @@ public class VolumeControlService extends ProfileService {
        Objects.requireNonNull(mAudioManager,
                "AudioManager cannot be null when VolumeControlService starts");

        mMusicMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        mMusicMinVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
        mVoiceCallMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
        mVoiceCallMinVolume = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);

        // Start handler thread for state machines
        mStateMachines.clear();
        mStateMachinesThread = new HandlerThread("VolumeControlService.StateMachines");
@@ -684,15 +672,11 @@ public class VolumeControlService extends ProfileService {
    }

    int getDeviceVolume(int streamType, int bleVolume) {
        int bleMaxVolume = 255; // min volume is zero
        int deviceMaxVolume = (streamType == AudioManager.STREAM_VOICE_CALL)
                ? mVoiceCallMaxVolume : mMusicMaxVolume;
        int deviceMinVolume = (streamType == AudioManager.STREAM_VOICE_CALL)
                ? mVoiceCallMinVolume : mMusicMinVolume;
        int deviceMaxVolume = mAudioManager.getStreamMaxVolume(streamType);

        // TODO: Investigate what happens in classic BT when BT volume is changed to zero.
        return (int) Math.floor(
                (double) bleVolume * (deviceMaxVolume - deviceMinVolume) / bleMaxVolume);
        double deviceVolume = (double) (bleVolume * deviceMaxVolume) / LE_AUDIO_MAX_VOL;
        return (int) Math.round(deviceVolume);
    }

    // Copied from AudioService.getBluetoothContextualVolumeStream() and modified it.
@@ -881,14 +865,6 @@ public class VolumeControlService extends ProfileService {
            sm = VolumeControlStateMachine.make(device, this,
                    mVolumeControlNativeInterface, mStateMachinesThread.getLooper());
            mStateMachines.put(device, sm);

            mAudioManager.setDeviceVolumeBehavior(
                    new AudioDeviceAttributes(
                            AudioDeviceAttributes.ROLE_OUTPUT,
                            // Currently, TYPE_BLUETOOTH_A2DP is the only thing that works.
                            AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
                            ""),
                    AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
            return sm;
        }
    }
+50 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeoutException;
import java.util.stream.IntStream;

@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -66,6 +67,11 @@ public class VolumeControlServiceTest {
    private BluetoothDevice mDevice;
    private HashMap<BluetoothDevice, LinkedBlockingQueue<Intent>> mDeviceQueueMap;
    private static final int TIMEOUT_MS = 1000;
    private static final int BT_LE_AUDIO_MAX_VOL = 255;
    private static final int MEDIA_MIN_VOL = 0;
    private static final int MEDIA_MAX_VOL = 25;
    private static final int CALL_MIN_VOL = 1;
    private static final int CALL_MAX_VOL = 8;

    private BroadcastReceiver mVolumeControlIntentReceiver;

@@ -92,6 +98,15 @@ public class VolumeControlServiceTest {

        mAdapter = BluetoothAdapter.getDefaultAdapter();

        doReturn(MEDIA_MIN_VOL).when(mAudioManager)
                .getStreamMinVolume(eq(AudioManager.STREAM_MUSIC));
        doReturn(MEDIA_MAX_VOL).when(mAudioManager)
                .getStreamMaxVolume(eq(AudioManager.STREAM_MUSIC));
        doReturn(CALL_MIN_VOL).when(mAudioManager)
                .getStreamMinVolume(eq(AudioManager.STREAM_VOICE_CALL));
        doReturn(CALL_MAX_VOL).when(mAudioManager)
                .getStreamMaxVolume(eq(AudioManager.STREAM_VOICE_CALL));

        startService();
        mService.mVolumeControlNativeInterface = mNativeInterface;
        mService.mAudioManager = mAudioManager;
@@ -514,6 +529,41 @@ public class VolumeControlServiceTest {
        mService.messageFromNative(stackEvent);
    }

    int getLeAudioVolume(int index, int minIndex, int maxIndex, int streamType) {
        // Note: This has to be the same as mBtHelper.setLeAudioVolume()
        return (int) Math.round((double) index * BT_LE_AUDIO_MAX_VOL / maxIndex);
    }

    void testVolumeCalculations(int streamType, int minIdx, int maxIdx) {
        // Send a message to trigger volume state changed broadcast
        final VolumeControlStackEvent stackEvent = new VolumeControlStackEvent(
                VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED);
        stackEvent.device = null;
        stackEvent.valueInt1 = 1;       // groupId
        stackEvent.valueBool1 = false;  // isMuted
        stackEvent.valueBool2 = true;   // isAutonomous

        IntStream.range(minIdx, maxIdx).forEach(idx -> {
            // Given the reference volume index, set the LeAudio Volume
            stackEvent.valueInt2 = getLeAudioVolume(idx,
                            mAudioManager.getStreamMinVolume(streamType),
                            mAudioManager.getStreamMaxVolume(streamType), streamType);
            mService.messageFromNative(stackEvent);

            // Verify that setting LeAudio Volume, sets the original volume index to Audio FW
            verify(mAudioManager, times(1)).setStreamVolume(eq(streamType), eq(idx), anyInt());
        });
    }

    @Test
    public void testAutonomousVolumeStateChange() {
        doReturn(AudioManager.MODE_IN_CALL).when(mAudioManager).getMode();
        testVolumeCalculations(AudioManager.STREAM_VOICE_CALL, CALL_MIN_VOL, CALL_MAX_VOL);

        doReturn(AudioManager.MODE_NORMAL).when(mAudioManager).getMode();
        testVolumeCalculations(AudioManager.STREAM_MUSIC, MEDIA_MIN_VOL, MEDIA_MAX_VOL);
    }

    /**
     * Test Volume Control cache.
     */