LE Audio Allowlist toggle behavior refactor
The patch contains below behavior changes
1. hide this toggle as the device doesn't enable LE audio profile
2. disable this toggle as bluetooth off, or LE audio feature is disabled
dynamically
3. disable this toggle if the device doesn't configure to use LE audio
connection by default
4. switch toggle on to bypass LE Audio allowlist
Bug: 300012501
Test: make RunSettingsRoboTests ROBOTEST_FILTER=BluetoothLeAudioAllowListPreferenceControllerTest
Change-Id: I5ae9c860ba22047fc03ffde7ad3b3f44f9a9a9f0
diff --git a/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java b/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java
index 532db85..cc43c2b 100644
--- a/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java
+++ b/src/com/android/settings/development/BluetoothLeAudioAllowListPreferenceController.java
@@ -21,6 +21,7 @@
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 @@
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 @@
super(context);
mFragment = fragment;
mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
+ mLeAudioConnectionByDefault =
+ SystemProperties.getBoolean(LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY, true);
}
@Override
@@ -62,29 +66,48 @@
}
@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 d85d522..4ac90a7 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 @@
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 @@
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 @@
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();
+ }
}