diff options
author | 2025-03-20 01:49:54 -0700 | |
---|---|---|
committer | 2025-03-21 13:05:33 -0700 | |
commit | 2369204a6f40d4a50a0b3bbb95fbfaa824d5523c (patch) | |
tree | d0187c60989ef205d52c0da10ee4812052724545 | |
parent | ab767cf58ed047da70e897afc4be5724f3ea96a5 (diff) |
headset: check property before showing ui
Take system property `bluetooth.hfp_volume_control.enabled` into
consideration when performing volume changes to determine
if volume ui should be displayed or not.
Similar check already present in HeadsetClientStateMachine.java
Bug: 348420422
Bug: 404152232
Test: atest BluetoothJavaUnitTests:HeadsetStateMachineTest
Test: adjust volume in call using handsfree while
`bluetooth.hfp_volume_control.enabled` is false.
Flag: com.android.bluetooth.flags.hfp_volume_control_property
Change-Id: I3cca9f580fb188ab37355d71b4c8a51699082efc
-rw-r--r-- | android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java | 9 | ||||
-rw-r--r-- | android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java | 48 |
2 files changed, 56 insertions, 1 deletions
diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java index 6ea741af32..3c2fe0f8bf 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetStateMachine.java @@ -58,6 +58,7 @@ import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.flags.Flags; +import com.android.bluetooth.util.SystemProperties; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -187,6 +188,9 @@ class HeadsetStateMachine extends StateMachine { BluetoothAssignedNumbers.GOOGLE); } + @VisibleForTesting + static final String HFP_VOLUME_CONTROL_ENABLED = "bluetooth.hfp_volume_control.enabled"; + private HeadsetStateMachine( BluetoothDevice device, Looper looper, @@ -2026,7 +2030,10 @@ class HeadsetStateMachine extends StateMachine { } if (volumeType == HeadsetHalConstants.VOLUME_TYPE_SPK) { mSpeakerVolume = volume; - int flag = (mCurrentState == mAudioOn) ? AudioManager.FLAG_SHOW_UI : 0; + boolean showVolume = + !Flags.hfpVolumeControlProperty() + || SystemProperties.getBoolean(HFP_VOLUME_CONTROL_ENABLED, true); + int flag = showVolume && (mCurrentState == mAudioOn) ? AudioManager.FLAG_SHOW_UI : 0; int volStream = deprecateStreamBtSco() ? AudioManager.STREAM_VOICE_CALL diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java index 9f4a2c1382..529110f7d2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetStateMachineTest.java @@ -69,10 +69,12 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ActiveDeviceManager; import com.android.bluetooth.btservice.AdapterService; +import com.android.bluetooth.btservice.PhonePolicy; import com.android.bluetooth.btservice.RemoteDevices; import com.android.bluetooth.btservice.SilenceDeviceManager; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.flags.Flags; +import com.android.bluetooth.util.SystemProperties; import org.junit.After; import org.junit.Before; @@ -121,6 +123,7 @@ public class HeadsetStateMachineTest { private MockContentResolver mMockContentResolver; @Mock private HeadsetNativeInterface mNativeInterface; @Mock private RemoteDevices mRemoteDevices; + @Mock private SystemProperties.MockableSystemProperties mProperties; @Before public void setUp() throws Exception { @@ -175,6 +178,8 @@ public class HeadsetStateMachineTest { mAdapterService, mNativeInterface, mSystemInterface); + + SystemProperties.mProperties = mProperties; } @After @@ -1765,6 +1770,49 @@ public class HeadsetStateMachineTest { verify(mockAudioManager).setStreamVolume(AudioManager.STREAM_VOICE_CALL, 2, 0); } + @RequiresFlagsEnabled(Flags.FLAG_HFP_VOLUME_CONTROL_PROPERTY) + @Test + public void testProcessVolumeEventAudioConnected_withVolumeControlEnabled_ShowUiFlagEnabled() { + doReturn(true) + .when(mProperties) + .getBoolean(eq(HeadsetStateMachine.HFP_VOLUME_CONTROL_ENABLED), anyBoolean()); + + setUpAudioOnState(); + + when(mHeadsetService.getActiveDevice()).thenReturn(mDevice); + AudioManager mockAudioManager = mock(AudioManager.class); + when(mockAudioManager.getStreamVolume(anyInt())).thenReturn(1); + when(mSystemInterface.getAudioManager()).thenReturn(mockAudioManager); + + mHeadsetStateMachine.processVolumeEvent(HeadsetHalConstants.VOLUME_TYPE_SPK, 2); + + var flagsCaptor = ArgumentCaptor.forClass(Integer.class); + verify(mockAudioManager).setStreamVolume(anyInt(), anyInt(), flagsCaptor.capture()); + assertThat(flagsCaptor.getValue() & AudioManager.FLAG_SHOW_UI) + .isEqualTo(AudioManager.FLAG_SHOW_UI); + } + + @RequiresFlagsEnabled(Flags.FLAG_HFP_VOLUME_CONTROL_PROPERTY) + @Test + public void testProcessVolumeEventAudioConnected_withVolumeControlEnabled_ShowUiFlagDisabled() { + doReturn(false) + .when(mProperties) + .getBoolean(eq(HeadsetStateMachine.HFP_VOLUME_CONTROL_ENABLED), anyBoolean()); + + setUpAudioOnState(); + + when(mHeadsetService.getActiveDevice()).thenReturn(mDevice); + AudioManager mockAudioManager = mock(AudioManager.class); + when(mockAudioManager.getStreamVolume(anyInt())).thenReturn(1); + when(mSystemInterface.getAudioManager()).thenReturn(mockAudioManager); + + mHeadsetStateMachine.processVolumeEvent(HeadsetHalConstants.VOLUME_TYPE_SPK, 2); + + var flagsCaptor = ArgumentCaptor.forClass(Integer.class); + verify(mockAudioManager).setStreamVolume(anyInt(), anyInt(), flagsCaptor.capture()); + assertThat(flagsCaptor.getValue() & AudioManager.FLAG_SHOW_UI).isEqualTo(0); + } + @Test public void testVolumeChangeEvent_fromIntentWhenAudioOn() { setUpAudioOnState(); |