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

Commit dd436693 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Gerrit Code Review
Browse files

Merge "VolumeControlService: Fix setting volume on active group" into main

parents aac10891 031513b4
Loading
Loading
Loading
Loading
+34 −19
Original line number Diff line number Diff line
@@ -495,17 +495,23 @@ public class LeAudioService extends ProfileService {
        sLeAudioService = instance;
    }

    @VisibleForTesting
    int getAudioDeviceGroupVolume(int groupId) {
    VolumeControlService getVolumeControlService() {
        if (mVolumeControlService == null) {
            mVolumeControlService = mServiceFactory.getVolumeControlService();
            if (mVolumeControlService == null) {
                Log.e(TAG, "Volume control service is not available");
                return IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME;
            }
        }
        return mVolumeControlService;
    }

        return mVolumeControlService.getAudioDeviceGroupVolume(groupId);
    @VisibleForTesting
    int getAudioDeviceGroupVolume(int groupId) {
        VolumeControlService volumeControlService = getVolumeControlService();
        if (volumeControlService == null) {
            return IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME;
        }
        return volumeControlService.getAudioDeviceGroupVolume(groupId);
    }

    LeAudioDeviceDescriptor createDeviceDescriptor(BluetoothDevice device,
@@ -1224,6 +1230,20 @@ public class LeAudioService extends ProfileService {
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        sendBroadcast(intent, BLUETOOTH_CONNECT);
    }

    void notifyVolumeControlServiceAboutActiveGroup(BluetoothDevice device) {
        VolumeControlService volumeControlService = getVolumeControlService();
        if (volumeControlService == null) {
            return;
        }

        if (mExposedActiveDevice != null) {
            volumeControlService.setGroupActive(getGroupId(mExposedActiveDevice), false);
        }

        volumeControlService.setGroupActive(getGroupId(device), true);
    }

    /**
     * Send broadcast intent about LeAudio active device.
     * This is called when AudioManager confirms, LeAudio device
@@ -1238,6 +1258,7 @@ public class LeAudioService extends ProfileService {

        mAdapterService.handleActiveDeviceChange(BluetoothProfile.LE_AUDIO, device);
        sentActiveDeviceChangeIntent(device);
        notifyVolumeControlServiceAboutActiveGroup(device);
        mExposedActiveDevice = device;
    }

@@ -2711,11 +2732,9 @@ public class LeAudioService extends ProfileService {
            Log.d(TAG, "setLeAudioGattClientProfilesPolicy for device " + device + " to policy="
                    + connectionPolicy);
        }
        if (mVolumeControlService == null) {
            mVolumeControlService = mServiceFactory.getVolumeControlService();
        }
        if (mVolumeControlService != null) {
            mVolumeControlService.setConnectionPolicy(device, connectionPolicy);
        VolumeControlService volumeControlService = getVolumeControlService();
        if (volumeControlService != null) {
            volumeControlService.setConnectionPolicy(device, connectionPolicy);
        }

        if (mHapClientService == null) {
@@ -2812,11 +2831,9 @@ public class LeAudioService extends ProfileService {
            return;
        }

        if (mVolumeControlService == null) {
            mVolumeControlService = mServiceFactory.getVolumeControlService();
        }
        if (mVolumeControlService != null) {
            mVolumeControlService.setGroupVolume(currentlyActiveGroupId, volume);
        VolumeControlService volumeControlService = getVolumeControlService();
        if (volumeControlService != null) {
            volumeControlService.setGroupVolume(currentlyActiveGroupId, volume);
        }
    }

@@ -2938,11 +2955,9 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyGroupNodeAdded(BluetoothDevice device, int groupId) {
        if (mVolumeControlService == null) {
            mVolumeControlService = mServiceFactory.getVolumeControlService();
        }
        if (mVolumeControlService != null) {
            mVolumeControlService.handleGroupNodeAdded(groupId, device);
        VolumeControlService volumeControlService = getVolumeControlService();
        if (volumeControlService != null) {
            volumeControlService.handleGroupNodeAdded(groupId, device);
        }

        if (mLeAudioCallbacks != null) {
+43 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
package com.android.bluetooth.vc;

import static android.Manifest.permission.BLUETOOTH_CONNECT;

import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;

import android.annotation.RequiresPermission;
@@ -639,6 +638,30 @@ public class VolumeControlService extends ProfileService {
                        IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME);
    }

    /**
     * This should be called by LeAudioService when LE Audio group change it
     * active state.
     *
     * @param groupId   the group identifier
     * @param active    indicator if group is active or not
     */
    public void setGroupActive(int groupId, boolean active) {
        if (DBG) {
            Log.d(TAG, "setGroupActive: " + groupId + ", active: " + active);
        }
        if (!active) {
            /* For now we don't need to handle group inactivation */
            return;
        }

        int groupVolume = getGroupVolume(groupId);
        Boolean groupMute = getGroupMute(groupId);

        if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
            updateGroupCacheAndAudioSystem(groupId, groupVolume, groupMute);
        }
    }

    /**
     * @param groupId the group identifier
     */
@@ -1384,6 +1407,25 @@ public class VolumeControlService extends ProfileService {
            }
        }

        @Override
        public void setGroupActive(
                int groupId,
                boolean active,
                AttributionSource source,
                SynchronousResultReceiver receiver) {
            try {
                Objects.requireNonNull(source, "source cannot be null");
                Objects.requireNonNull(receiver, "receiver cannot be null");

                VolumeControlService service = getService(source);
                receiver.send(null);
                if (service != null) {
                    service.setGroupActive(groupId, active);
                }
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        @Override
        public void mute(BluetoothDevice device,  AttributionSource source,
+37 −0
Original line number Diff line number Diff line
@@ -677,6 +677,43 @@ public class VolumeControlServiceTest {
        Assert.assertEquals(volume, mService.getGroupVolume(groupId));
    }

    /** Test Active Group change */
    @Test
    public void testActiveGroupChange() throws Exception {
        int groupId_1 = 1;
        int volume_groupId_1 = 6;

        int groupId_2 = 2;
        int volume_groupId_2 = 20;

        Assert.assertEquals(-1, mService.getGroupVolume(groupId_1));
        Assert.assertEquals(-1, mService.getGroupVolume(groupId_2));
        SynchronousResultReceiver<Void> voidRecv = SynchronousResultReceiver.get();
        mServiceBinder.setGroupVolume(groupId_1, volume_groupId_1, mAttributionSource, voidRecv);
        voidRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS));

        voidRecv = SynchronousResultReceiver.get();
        mServiceBinder.setGroupVolume(groupId_2, volume_groupId_2, mAttributionSource, voidRecv);
        voidRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS));

        voidRecv = SynchronousResultReceiver.get();
        mServiceBinder.setGroupActive(groupId_1, true, mAttributionSource, voidRecv);
        voidRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS));

        // Expected index for STREAM_MUSIC
        int expectedVol =
                (int) Math.round((double) (volume_groupId_1 * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
        verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedVol), anyInt());

        voidRecv = SynchronousResultReceiver.get();
        mServiceBinder.setGroupActive(groupId_2, true, mAttributionSource, voidRecv);

        expectedVol =
                (int) Math.round((double) (volume_groupId_2 * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
        verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedVol), anyInt());
        voidRecv.awaitResultNoInterrupt(Duration.ofMillis(TIMEOUT_MS));
    }

    /**
     * Test Volume Control Mute cache.
     */
+3 −0
Original line number Diff line number Diff line
@@ -56,6 +56,9 @@ oneway interface IBluetoothVolumeControl {
    void setGroupVolume(int group_id, int volume, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
    void getGroupVolume(int group_id, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
    void setGroupActive(int group_id, boolean active, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);


    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
    void mute(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);