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

Commit b2336ea7 authored by Alice Kuo's avatar Alice Kuo
Browse files

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
parent f8767cdd
Loading
Loading
Loading
Loading
+39 −16
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.content.Context;
import android.os.SystemProperties;
import android.os.SystemProperties;
import android.sysprop.BluetoothProperties;


import androidx.annotation.VisibleForTesting;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
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 PREFERENCE_KEY = "bluetooth_bypass_leaudio_allowlist";


    private static final String LE_AUDIO_ALLOW_LIST_SWITCH_SUPPORT_PROPERTY =
    static final String LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY =
            "ro.bluetooth.leaudio_allow_list.supported";
            "ro.bluetooth.leaudio.le_audio_connection_by_default";
    @VisibleForTesting
    @VisibleForTesting
    static final String LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY =
    static final String BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY =
            "persist.bluetooth.leaudio.enable_allow_list";
            "persist.bluetooth.leaudio.bypass_allow_list";


    @VisibleForTesting
    @VisibleForTesting
    BluetoothAdapter mBluetoothAdapter;
    BluetoothAdapter mBluetoothAdapter;
    @VisibleForTesting boolean mLeAudioConnectionByDefault;


    private final DevelopmentSettingsDashboardFragment mFragment;
    private final DevelopmentSettingsDashboardFragment mFragment;


@@ -54,6 +56,8 @@ public class BluetoothLeAudioAllowListPreferenceController
        super(context);
        super(context);
        mFragment = fragment;
        mFragment = fragment;
        mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
        mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
        mLeAudioConnectionByDefault =
                SystemProperties.getBoolean(LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY, true);
    }
    }


    @Override
    @Override
@@ -61,30 +65,49 @@ public class BluetoothLeAudioAllowListPreferenceController
        return PREFERENCE_KEY;
        return PREFERENCE_KEY;
    }
    }


    @Override
    public boolean isAvailable() {
        return BluetoothProperties.isProfileBapUnicastClientEnabled().orElse(false)
                && mLeAudioConnectionByDefault;
    }

    @Override
    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
    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
    @Override
    public void updateState(Preference preference) {
    public void updateState(Preference preference) {
        if (mBluetoothAdapter == null) {
        if (mBluetoothAdapter == null) {
            mPreference.setEnabled(false);
            return;
            return;
        }
        }


        final int leAudioSupportedState = mBluetoothAdapter.isLeAudioSupported();
        final boolean isLeAudioSupported =
        final boolean leAudioEnabled =
                (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED);
                (leAudioSupportedState == BluetoothStatusCodes.FEATURE_SUPPORTED);
        if (!isLeAudioSupported) {
        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 {
            mPreference.setEnabled(false);
            mPreference.setEnabled(false);
            ((SwitchPreference) mPreference).setChecked(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);
        }
        }
    }
    }
}
}
+48 −6
Original line number Original line Diff line number Diff line
@@ -18,16 +18,24 @@ package com.android.settings.development;


import static android.bluetooth.BluetoothStatusCodes.FEATURE_SUPPORTED;
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.spy;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Context;
import android.os.SystemProperties;


import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.preference.SwitchPreference;


import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;
@@ -41,20 +49,18 @@ public class BluetoothLeAudioAllowListPreferenceControllerTest {
    private PreferenceScreen mPreferenceScreen;
    private PreferenceScreen mPreferenceScreen;
    @Mock
    @Mock
    private DevelopmentSettingsDashboardFragment mFragment;
    private DevelopmentSettingsDashboardFragment mFragment;

    @Mock
    @Mock
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothAdapter mBluetoothAdapter;

    @Mock
    private Context mContext;
    private SwitchPreference mPreference;
    private SwitchPreference mPreference;
    private BluetoothLeAudioPreferenceController mController;
    private Context mContext;
    private BluetoothLeAudioAllowListPreferenceController mController;


    @Before
    @Before
    public void setup() {
    public void setup() {
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        mContext = RuntimeEnvironment.application;
        mPreference = new SwitchPreference(mContext);
        mController = spy(new BluetoothLeAudioAllowListPreferenceController(mContext, mFragment));
        mController = spy(new BluetoothLeAudioPreferenceController(mContext, mFragment));
        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
            .thenReturn(mPreference);
            .thenReturn(mPreference);
        mController.mBluetoothAdapter = mBluetoothAdapter;
        mController.mBluetoothAdapter = mBluetoothAdapter;
@@ -62,4 +68,40 @@ public class BluetoothLeAudioAllowListPreferenceControllerTest {
        when(mBluetoothAdapter.isLeAudioSupported())
        when(mBluetoothAdapter.isLeAudioSupported())
            .thenReturn(FEATURE_SUPPORTED);
            .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();
    }
}
}