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

Commit de411084 authored by Jakub Tyszkowski (xWF)'s avatar Jakub Tyszkowski (xWF) Committed by Gerrit Code Review
Browse files

Merge "VolumeControl: Fix restoring earbuds volume" into main

parents 5b8923f0 aecd8441
Loading
Loading
Loading
Loading
+24 −7
Original line number Diff line number Diff line
@@ -785,12 +785,13 @@ public class VolumeControlService extends ProfileService {
                            + (", flags: " + flags));
            /* We are here, because system has just started and LeAudio device is connected. If
             * remote device has User Persistent flag set, Android sets the volume to local cache
             * and to the audio system.
             * and to the audio system if not already streaming to other devices.
             * If Reset Flag is set, then Android sets to remote devices either cached volume volume
             * taken from audio manager.
             * Note, to match BR/EDR behavior, don't show volume change in UI here
             */
            if ((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01) {
            if (((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01)
                    && (getConnectedDevices().size() == 1)) {
                updateGroupCacheAndAudioSystem(groupId, volume, mute, false);
                return;
            }
@@ -1138,12 +1139,12 @@ public class VolumeControlService extends ProfileService {
        input.setPropSettings(id, unit, min, max);
    }

    void messageFromNative(VolumeControlStackEvent stackEvent) {
    void handleStackEvent(VolumeControlStackEvent stackEvent) {
        if (!isAvailable()) {
            Log.e(TAG, "Event ignored, service not available: " + stackEvent);
            return;
        }
        Log.d(TAG, "messageFromNative: " + stackEvent);
        Log.d(TAG, "handleStackEvent: " + stackEvent);

        if (stackEvent.type == VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED) {
            handleVolumeControlChanged(
@@ -1182,20 +1183,36 @@ public class VolumeControlService extends ProfileService {
            return;
        }

        Log.e(TAG, "Unhandled event: " + stackEvent);
    }

    void messageFromNative(VolumeControlStackEvent stackEvent) {
        Log.d(TAG, "messageFromNative: " + stackEvent);

        // Group events should be handled here directly
        boolean isGroupEvent = (stackEvent.device == null);
        if (isGroupEvent) {
            handleStackEvent(stackEvent);
            return;
        }

        // Other device events should be serialized via their state machines so they are processed
        // in the same order they were sent from the native code.
        synchronized (mStateMachines) {
            VolumeControlStateMachine sm = mStateMachines.get(device);
            VolumeControlStateMachine sm = mStateMachines.get(stackEvent.device);
            if (sm == null) {
                if (stackEvent.type
                        == VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
                    switch (stackEvent.valueInt1) {
                        case STATE_CONNECTED, STATE_CONNECTING -> {
                            sm = getOrCreateStateMachine(device);
                            sm = getOrCreateStateMachine(stackEvent.device);
                        }
                    }
                }
            }
            if (sm == null) {
                Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
                Log.w(TAG, "Cannot forward stack event: no state machine: " + stackEvent);
                handleStackEvent(stackEvent);
                return;
            }
            sm.sendMessage(VolumeControlStateMachine.MESSAGE_STACK_EVENT, stackEvent);
+0 −2
Original line number Diff line number Diff line
@@ -102,8 +102,6 @@ public class VolumeControlStackEvent {

    private static String eventTypeValue2ToString(int type, int value) {
        switch (type) {
            case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                return BluetoothProfile.getConnectionStateName(value);
            case EVENT_TYPE_VOLUME_STATE_CHANGED:
                return "{volume:" + value + "}";
            case EVENT_TYPE_DEVICE_AVAILABLE:
+18 −4
Original line number Diff line number Diff line
@@ -157,7 +157,10 @@ class VolumeControlStateMachine extends StateMachine {
                        case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
                            processConnectionEvent(event.valueInt1);
                        }
                        default -> Log.e(TAG, "Disconnected: ignoring stack event: " + event);
                        default -> {
                            Log.e(TAG, "Disconnected: forwarding stack event: " + event);
                            mService.handleStackEvent(event);
                        }
                    }
                }
                default -> {
@@ -262,7 +265,14 @@ class VolumeControlStateMachine extends StateMachine {
                        case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
                            processConnectionEvent(event.valueInt1);
                        }
                        default -> Log.e(TAG, "Connecting: ignoring stack event: " + event);
                        case VolumeControlStackEvent.EVENT_TYPE_VOLUME_STATE_CHANGED -> {
                            Log.w(TAG, "Defer volume change received while connecting: " + mDevice);
                            deferMessage(message);
                        }
                        default -> {
                            Log.e(TAG, "Connecting: forwarding stack event: " + event);
                            mService.handleStackEvent(event);
                        }
                    }
                }
                default -> {
@@ -355,7 +365,10 @@ class VolumeControlStateMachine extends StateMachine {
                        case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
                            processConnectionEvent(event.valueInt1);
                        }
                        default -> Log.e(TAG, "Disconnecting: ignoring stack event: " + event);
                        default -> {
                            Log.e(TAG, "Disconnecting: forwarding stack event: " + event);
                            mService.handleStackEvent(event);
                        }
                    }
                }
                default -> {
@@ -452,7 +465,8 @@ class VolumeControlStateMachine extends StateMachine {
                            processConnectionEvent(event.valueInt1);
                        }
                        default -> {
                            Log.e(TAG, "Connected: ignoring stack event: " + event);
                            Log.e(TAG, "Connected: forwarding stack event: " + event);
                            mService.handleStackEvent(event);
                        }
                    }
                }
+11 −4
Original line number Diff line number Diff line
@@ -610,8 +610,8 @@ public class VolumeControlServiceTest {
                (int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
        verify(mAudioManager).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());

        // Connect second device and read different volume. Expect it will be set to AF and to
        // another set member
        // Connect second device and read different volume. Expect it will NOT be set to AF
        // and to another set member, but the existing volume gets applied to it
        generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
        generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
        assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
@@ -625,9 +625,12 @@ public class VolumeControlServiceTest {
                flags,
                initialMuteState,
                initialAutonomousFlag);
        expectedAfVol =

        expectedAfVol = volumeDevice;
        int unexpectedAfVol =
                (int) Math.round((double) (volumeDeviceTwo * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
        verify(mAudioManager).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
        verify(mAudioManager, times(0)).setStreamVolume(anyInt(), eq(unexpectedAfVol), anyInt());
        verify(mNativeInterface).setGroupVolume(eq(groupId), eq(expectedAfVol));
    }

    private void testConnectedDeviceWithResetFlag(
@@ -1276,6 +1279,7 @@ public class VolumeControlServiceTest {
        stackEvent.valueBool1 = mute;
        stackEvent.valueBool2 = isAutonomous;
        mService.messageFromNative(stackEvent);
        mLooper.dispatchAll();
    }

    private void generateDeviceOffsetChangedMessageFromNative(
@@ -1288,6 +1292,7 @@ public class VolumeControlServiceTest {
        event.valueInt1 = extOffsetIndex; // external output index
        event.valueInt2 = offset; // offset value
        mService.messageFromNative(event);
        mLooper.dispatchAll();
    }

    private void generateDeviceLocationChangedMessageFromNative(
@@ -1300,6 +1305,7 @@ public class VolumeControlServiceTest {
        event.valueInt1 = extOffsetIndex; // external output index
        event.valueInt2 = location; // location
        mService.messageFromNative(event);
        mLooper.dispatchAll();
    }

    private void generateDeviceDescriptionChangedMessageFromNative(
@@ -1312,6 +1318,7 @@ public class VolumeControlServiceTest {
        event.valueInt1 = extOffsetIndex; // external output index
        event.valueString1 = description; // description
        mService.messageFromNative(event);
        mLooper.dispatchAll();
    }

    @SafeVarargs