Loading android/app/src/com/android/bluetooth/vc/VolumeControlService.java +17 −14 Original line number Diff line number Diff line Loading @@ -805,15 +805,18 @@ public class VolumeControlService extends ProfileService { + (", mute: " + mute) + (", flags: " + flags)); /* We are here, because system has just started and LeAudio device is connected. If * remote device has User Persistent flag set or the volume != 0, Android sets the * volume to local cache and to the audio system. If Reset Flag is set and remote has * volume set to 0, 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 * remote device has User Persistent flag set, Android sets the volume to local cache * and to the audio system. * 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 || (volume != 0)) { if ((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01) { updateGroupCacheAndAudioSystem(groupId, volume, mute, false); } else { return; } // Reset flag is used if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) { Log.i(TAG, "Setting volume: " + groupVolume + " to the group: " + groupId); setGroupVolume(groupId, groupVolume); Loading @@ -822,7 +825,7 @@ public class VolumeControlService extends ProfileService { Log.i(TAG, "Setting system volume: " + vol + " to the group: " + groupId); setGroupVolume(groupId, getBleVolumeFromCurrentStream()); } } return; } Loading android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java +30 −76 Original line number Diff line number Diff line Loading @@ -804,79 +804,15 @@ public class VolumeControlServiceTest { verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt()); } /** Test if phone will set volume which is read from the buds */ @Test public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception { private void testConnectedDeviceWithResetFlag( int resetVolumeDeviceOne, int resetVolumeDeviceTwo) { int groupId = 1; int volumeDevice = 56; int volumeDeviceTwo = 100; int flags = 0; boolean initialMuteState = false; boolean initialAutonomousFlag = true; // Both devices are in the same group when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId); when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId); // Update the device policy so okToConnect() returns true when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); when(mDatabaseManager.getProfileConnectionPolicy( any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL))) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class)); generateDeviceAvailableMessageFromNative(mDevice, 1); generateConnectionMessageFromNative( mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); Assert.assertTrue(mService.getDevices().contains(mDevice)); // Group is not active, AF will not be notified generateVolumeStateChanged( mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag); verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt()); // Make device Active now. This will trigger setting volume to AF when(mLeAudioService.getActiveGroupId()).thenReturn(groupId); mServiceBinder.setGroupActive(groupId, true, mAttributionSource); int expectedAfVol = (int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt()); // Connect second device and read different volume. Expect it will be set to AF and to // another set member generateDeviceAvailableMessageFromNative(mDeviceTwo, 1); generateConnectionMessageFromNative( mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals( BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo)); Assert.assertTrue(mService.getDevices().contains(mDeviceTwo)); // Group is now active, AF will be notified. Native will take care to sync the volume generateVolumeStateChanged( mDeviceTwo, groupId, volumeDeviceTwo, flags, initialMuteState, initialAutonomousFlag); expectedAfVol = (int) Math.round((double) (volumeDeviceTwo * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt()); } int streamVolume = 30; int streamMaxVolume = 100; int resetFlag = 0; /** Test if phone will set volume to buds which has no volume */ @Test public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception { int groupId = 1; int volumeDevice = 0; int volumeDeviceTwo = 0; int flags = 0; boolean initialMuteState = false; boolean initialAutonomousFlag = true; int streamVolume = 50; int streamMaxVolume = 100; // Both devices are in the same group when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId); Loading @@ -899,19 +835,25 @@ public class VolumeControlServiceTest { Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); Assert.assertTrue(mService.getDevices().contains(mDevice)); // Group is not active, AF will not be notified but device will get phone volume int expectedDeviceVol = int expectedAfVol = (int) Math.round((double) streamVolume * BT_LE_AUDIO_MAX_VOL / streamMaxVolume); // Group is not active, AF will not be notified generateVolumeStateChanged( mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag); mDevice, groupId, resetVolumeDeviceOne, resetFlag, initialMuteState, initialAutonomousFlag); verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt()); verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedDeviceVol)); // Make device Active now. This will trigger setting volume to AF when(mLeAudioService.getActiveGroupId()).thenReturn(groupId); mServiceBinder.setGroupActive(groupId, true, mAttributionSource); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(streamVolume), anyInt()); verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedAfVol)); // Connect second device and read different volume. Expect it will be set to AF and to // another set member Loading @@ -926,13 +868,25 @@ public class VolumeControlServiceTest { generateVolumeStateChanged( mDeviceTwo, groupId, volumeDeviceTwo, flags, resetVolumeDeviceTwo, resetFlag, initialMuteState, initialAutonomousFlag); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), anyInt(), anyInt()); verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedDeviceVol)); verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedAfVol)); } /** Test if phone will set volume which is read from the buds */ @Test public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception { testConnectedDeviceWithResetFlag(56, 100); } /** Test if phone will set volume to buds which has no volume */ @Test public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception { testConnectedDeviceWithResetFlag(0, 0); } /** Loading Loading
android/app/src/com/android/bluetooth/vc/VolumeControlService.java +17 −14 Original line number Diff line number Diff line Loading @@ -805,15 +805,18 @@ public class VolumeControlService extends ProfileService { + (", mute: " + mute) + (", flags: " + flags)); /* We are here, because system has just started and LeAudio device is connected. If * remote device has User Persistent flag set or the volume != 0, Android sets the * volume to local cache and to the audio system. If Reset Flag is set and remote has * volume set to 0, 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 * remote device has User Persistent flag set, Android sets the volume to local cache * and to the audio system. * 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 || (volume != 0)) { if ((flags & VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK) == 0x01) { updateGroupCacheAndAudioSystem(groupId, volume, mute, false); } else { return; } // Reset flag is used if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) { Log.i(TAG, "Setting volume: " + groupVolume + " to the group: " + groupId); setGroupVolume(groupId, groupVolume); Loading @@ -822,7 +825,7 @@ public class VolumeControlService extends ProfileService { Log.i(TAG, "Setting system volume: " + vol + " to the group: " + groupId); setGroupVolume(groupId, getBleVolumeFromCurrentStream()); } } return; } Loading
android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java +30 −76 Original line number Diff line number Diff line Loading @@ -804,79 +804,15 @@ public class VolumeControlServiceTest { verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt()); } /** Test if phone will set volume which is read from the buds */ @Test public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception { private void testConnectedDeviceWithResetFlag( int resetVolumeDeviceOne, int resetVolumeDeviceTwo) { int groupId = 1; int volumeDevice = 56; int volumeDeviceTwo = 100; int flags = 0; boolean initialMuteState = false; boolean initialAutonomousFlag = true; // Both devices are in the same group when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId); when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId); // Update the device policy so okToConnect() returns true when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager); when(mDatabaseManager.getProfileConnectionPolicy( any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL))) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class)); doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class)); generateDeviceAvailableMessageFromNative(mDevice, 1); generateConnectionMessageFromNative( mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); Assert.assertTrue(mService.getDevices().contains(mDevice)); // Group is not active, AF will not be notified generateVolumeStateChanged( mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag); verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt()); // Make device Active now. This will trigger setting volume to AF when(mLeAudioService.getActiveGroupId()).thenReturn(groupId); mServiceBinder.setGroupActive(groupId, true, mAttributionSource); int expectedAfVol = (int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt()); // Connect second device and read different volume. Expect it will be set to AF and to // another set member generateDeviceAvailableMessageFromNative(mDeviceTwo, 1); generateConnectionMessageFromNative( mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals( BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo)); Assert.assertTrue(mService.getDevices().contains(mDeviceTwo)); // Group is now active, AF will be notified. Native will take care to sync the volume generateVolumeStateChanged( mDeviceTwo, groupId, volumeDeviceTwo, flags, initialMuteState, initialAutonomousFlag); expectedAfVol = (int) Math.round((double) (volumeDeviceTwo * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt()); } int streamVolume = 30; int streamMaxVolume = 100; int resetFlag = 0; /** Test if phone will set volume to buds which has no volume */ @Test public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception { int groupId = 1; int volumeDevice = 0; int volumeDeviceTwo = 0; int flags = 0; boolean initialMuteState = false; boolean initialAutonomousFlag = true; int streamVolume = 50; int streamMaxVolume = 100; // Both devices are in the same group when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId); Loading @@ -899,19 +835,25 @@ public class VolumeControlServiceTest { Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); Assert.assertTrue(mService.getDevices().contains(mDevice)); // Group is not active, AF will not be notified but device will get phone volume int expectedDeviceVol = int expectedAfVol = (int) Math.round((double) streamVolume * BT_LE_AUDIO_MAX_VOL / streamMaxVolume); // Group is not active, AF will not be notified generateVolumeStateChanged( mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag); mDevice, groupId, resetVolumeDeviceOne, resetFlag, initialMuteState, initialAutonomousFlag); verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt()); verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedDeviceVol)); // Make device Active now. This will trigger setting volume to AF when(mLeAudioService.getActiveGroupId()).thenReturn(groupId); mServiceBinder.setGroupActive(groupId, true, mAttributionSource); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), eq(streamVolume), anyInt()); verify(mNativeInterface, times(1)).setGroupVolume(eq(groupId), eq(expectedAfVol)); // Connect second device and read different volume. Expect it will be set to AF and to // another set member Loading @@ -926,13 +868,25 @@ public class VolumeControlServiceTest { generateVolumeStateChanged( mDeviceTwo, groupId, volumeDeviceTwo, flags, resetVolumeDeviceTwo, resetFlag, initialMuteState, initialAutonomousFlag); verify(mAudioManager, times(1)).setStreamVolume(anyInt(), anyInt(), anyInt()); verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedDeviceVol)); verify(mNativeInterface, times(2)).setGroupVolume(eq(groupId), eq(expectedAfVol)); } /** Test if phone will set volume which is read from the buds */ @Test public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception { testConnectedDeviceWithResetFlag(56, 100); } /** Test if phone will set volume to buds which has no volume */ @Test public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception { testConnectedDeviceWithResetFlag(0, 0); } /** Loading