diff --git a/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java index 532db85373e..cc43c2becc2 100644 --- a/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java +++ b/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java @@ -21,6 +21,7 @@ import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.os.SystemProperties; +import android.sysprop.BluetoothProperties; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -38,14 +39,15 @@ public class BluetoothLeAudioAllowListPreferenceController private static final String PREFERENCE_KEY = "bluetooth_bypass_leaudio_allowlist"; - private static final String LE_AUDIO_ALLOW_LIST_SWITCH_SUPPORT_PROPERTY = - "ro.bluetooth.leaudio_allow_list.supported"; + static final String LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY = + "ro.bluetooth.leaudio.le_audio_connection_by_default"; @VisibleForTesting - static final String LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY = - "persist.bluetooth.leaudio.enable_allow_list"; + static final String BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY = + "persist.bluetooth.leaudio.bypass_allow_list"; @VisibleForTesting BluetoothAdapter mBluetoothAdapter; + @VisibleForTesting boolean mLeAudioConnectionByDefault; private final DevelopmentSettingsDashboardFragment mFragment; @@ -54,6 +56,8 @@ public class BluetoothLeAudioAllowListPreferenceController super(context); mFragment = fragment; mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); + mLeAudioConnectionByDefault = + SystemProperties.getBoolean(LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY, true); } @Override @@ -61,30 +65,49 @@ public class BluetoothLeAudioAllowListPreferenceController return PREFERENCE_KEY; } + @Override + public boolean isAvailable() { + return BluetoothProperties.isProfileBapUnicastClientEnabled().orElse(false) + && mLeAudioConnectionByDefault; + } + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - return false; + final boolean isBypassed = (Boolean) newValue; + SystemProperties.set(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, + isBypassed ? "true" : "false"); + return true; } @Override public void updateState(Preference preference) { if (mBluetoothAdapter == null) { + mPreference.setEnabled(false); return; } - final int leAudioSupportedState = mBluetoothAdapter.isLeAudioSupported(); - final boolean leAudioEnabled = - (leAudioSupportedState == BluetoothStatusCodes.FEATURE_SUPPORTED); - final boolean leAudioAllowListSupport = - SystemProperties.getBoolean(LE_AUDIO_ALLOW_LIST_SWITCH_SUPPORT_PROPERTY, false); - - if (leAudioEnabled && leAudioAllowListSupport) { - final boolean leAudioAllowListEnabled = - SystemProperties.getBoolean(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false); - ((SwitchPreference) mPreference).setChecked(!leAudioAllowListEnabled); - } else { + final boolean isLeAudioSupported = + (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED); + if (!isLeAudioSupported) { mPreference.setEnabled(false); ((SwitchPreference) mPreference).setChecked(false); + return; + } + + mPreference.setEnabled(true); + final boolean isLeAudioAllowlistBypassed = + SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, false); + ((SwitchPreference) mPreference).setChecked(isLeAudioAllowlistBypassed); + } + + @Override + protected void onDeveloperOptionsSwitchDisabled() { + super.onDeveloperOptionsSwitchDisabled(); + final boolean isBypassed = + SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, false); + if (isBypassed) { + SystemProperties.set(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, Boolean.toString(false)); + ((SwitchPreference) mPreference).setChecked(false); } } } diff --git a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceControllerTest.java index d85d522b2e0..4ac90a77f6e 100644 --- a/tests/robotests/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceControllerTest.java @@ -18,16 +18,24 @@ package com.android.settings.development; import static android.bluetooth.BluetoothStatusCodes.FEATURE_SUPPORTED; +import static com.android.settings.development.BluetoothLeAudioAllowListPreferenceController + .BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY; + +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; import android.bluetooth.BluetoothAdapter; import android.content.Context; +import android.os.SystemProperties; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -41,20 +49,18 @@ public class BluetoothLeAudioAllowListPreferenceControllerTest { private PreferenceScreen mPreferenceScreen; @Mock private DevelopmentSettingsDashboardFragment mFragment; - @Mock private BluetoothAdapter mBluetoothAdapter; - - private Context mContext; + @Mock private SwitchPreference mPreference; - private BluetoothLeAudioPreferenceController mController; + private Context mContext; + private BluetoothLeAudioAllowListPreferenceController mController; @Before public void setup() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - mPreference = new SwitchPreference(mContext); - mController = spy(new BluetoothLeAudioPreferenceController(mContext, mFragment)); + mController = spy(new BluetoothLeAudioAllowListPreferenceController(mContext, mFragment)); when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) .thenReturn(mPreference); mController.mBluetoothAdapter = mBluetoothAdapter; @@ -62,4 +68,40 @@ public class BluetoothLeAudioAllowListPreferenceControllerTest { when(mBluetoothAdapter.isLeAudioSupported()) .thenReturn(FEATURE_SUPPORTED); } + + @Test + public void onPreferenceChange_setCheck_shouldBypassLeAudioAllowlist() { + mController.onPreferenceChange(mPreference, Boolean.TRUE); + assertThat(SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, + false)).isTrue(); + } + + @Test + public void onPreferenceChange_setUnCheck_shouldNotBypassLeAudioAllowlist() { + mController.onPreferenceChange(mPreference, Boolean.FALSE); + assertThat(SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, + true)).isFalse(); + } + + @Test + public void updateState_bluetoothOff_shouldDisableToggle() { + mController.mBluetoothAdapter = null; + mController.updateState(mPreference); + verify(mPreference).setEnabled(false); + } + + @Test + public void updateState_bluetoothOn_shouldShowStatus() { + SystemProperties.set(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, Boolean.toString(true)); + mController.updateState(mPreference); + verify(mPreference).setChecked(true); + } + + @Test + public void onDeveloperOptionsSwitchDisabled_shouldSetBypassLeAudioAllowlistToFalse() { + SystemProperties.set(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, Boolean.toString(true)); + mController.onDeveloperOptionsSwitchDisabled(); + verify(mPreference).setEnabled(false); + assertThat(SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, true)).isFalse(); + } }