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

Commit 9745460c authored by Patty Huang's avatar Patty Huang Committed by Automerger Merge Worker
Browse files

Merge "Add LE Audio allow list feature switcher in the developer option menu"...

Merge "Add LE Audio allow list feature switcher in the developer option menu" am: 5bb798f5 am: 0086b200 am: ced8230e

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Settings/+/2387973



Change-Id: I30cf2f5e5fcf534877986839aba2f908b8f3b461
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 3e7889ce ced8230e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -228,6 +228,11 @@
    <!-- Summary of checkbox for enabling Bluetooth LE audio [CHAR LIMIT=none]-->
    <string name="bluetooth_enable_leaudio_summary">Enables Bluetooth LE audio feature if the device supports LE audio hardware capabilities.</string>
    <!-- Setting Checkbox title for enabling Bluetooth LE Audio Allow List. [CHAR LIMIT=none] -->
    <string name="bluetooth_enable_leaudio_allow_list">Enable Bluetooth LE audio Allow List</string>
    <!-- Summary of checkbox for enabling Bluetooth LE audio Allow List [CHAR LIMIT=none]-->
    <string name="bluetooth_enable_leaudio_allow_list_summary">Enable Bluetooth LE audio allow list feature.</string>
    <!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
    <string name="connected_device_media_device_title">Media devices</string>
    <!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
+5 −0
Original line number Diff line number Diff line
@@ -345,6 +345,11 @@
            android:title="@string/bluetooth_enable_leaudio"
            android:summary="@string/bluetooth_enable_leaudio_summary" />

        <SwitchPreference
            android:key="bluetooth_enable_leaudio_allow_list"
            android:title="@string/bluetooth_enable_leaudio_allow_list"
            android:summary="@string/bluetooth_enable_leaudio_allow_list_summary" />

        <SwitchPreference
            android:key="bluetooth_disable_le_audio_hw_offload"
            android:title="@string/bluetooth_disable_le_audio_hw_offload" />
+129 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.development;

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

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;

/**
 * Preference controller to control Bluetooth LE audio feature
 */
public class BluetoothLeAudioAllowListPreferenceController
        extends DeveloperOptionsPreferenceController
        implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {

    private static final String PREFERENCE_KEY = "bluetooth_enable_leaudio_allow_list";

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

    private static final String LE_AUDIO_DYNAMIC_SWITCH_PROPERTY =
            "ro.bluetooth.leaudio_switcher.supported";
    @VisibleForTesting
    static final String LE_AUDIO_DYNAMIC_ENABLED_PROPERTY =
            "persist.bluetooth.leaudio_switcher.enabled";

    @VisibleForTesting
    BluetoothAdapter mBluetoothAdapter;

    private final DevelopmentSettingsDashboardFragment mFragment;

    @VisibleForTesting
    boolean mChanged = false;

    public BluetoothLeAudioAllowListPreferenceController(Context context,
            DevelopmentSettingsDashboardFragment fragment) {
        super(context);
        mFragment = fragment;
        mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
    }

    @Override
    public String getPreferenceKey() {
        return PREFERENCE_KEY;
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        BluetoothRebootDialog.show(mFragment);
        mChanged = true;
        return false;
    }

    @Override
    public void updateState(Preference preference) {
        if (mBluetoothAdapter == null) {
            return;
        }

        int leAudioSupportedState = mBluetoothAdapter.isLeAudioSupported();
        boolean leAudioEnabled = false;

        if ((leAudioSupportedState == BluetoothStatusCodes.FEATURE_SUPPORTED)
                || (leAudioSupportedState == BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED
                && SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_SWITCH_PROPERTY, false)
                && SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, false))) {
            leAudioEnabled = true;
        }

        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);
            ((SwitchPreference) mPreference).setChecked(false);
        }
    }

    /**
     * Called when the RebootDialog confirm is clicked.
     */
    public void onRebootDialogConfirmed() {
        if (!mChanged) {
            return;
        }

        final boolean leAudioAllowListEnabled =
                SystemProperties.getBoolean(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
        SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY,
                Boolean.toString(!leAudioAllowListEnabled));
    }

    /**
     * Called when the RebootDialog cancel is clicked.
     */
    public void onRebootDialogCanceled() {
        mChanged = false;
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -389,6 +389,11 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
                getDevelopmentOptionsController(
                        BluetoothLeAudioPreferenceController.class);
        leAudioFeatureController.onRebootDialogConfirmed();

        final BluetoothLeAudioAllowListPreferenceController leAudioAllowListController =
                getDevelopmentOptionsController(
                    BluetoothLeAudioAllowListPreferenceController.class);
        leAudioAllowListController.onRebootDialogConfirmed();
    }

    @Override
@@ -406,6 +411,11 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
                getDevelopmentOptionsController(
                        BluetoothLeAudioPreferenceController.class);
        leAudioFeatureController.onRebootDialogCanceled();

        final BluetoothLeAudioAllowListPreferenceController leAudioAllowListController =
                getDevelopmentOptionsController(
                    BluetoothLeAudioAllowListPreferenceController.class);
        leAudioAllowListController.onRebootDialogCanceled();
    }

    @Override
@@ -602,6 +612,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
        controllers.add(new BluetoothAvrcpVersionPreferenceController(context));
        controllers.add(new BluetoothMapVersionPreferenceController(context));
        controllers.add(new BluetoothLeAudioPreferenceController(context, fragment));
        controllers.add(new BluetoothLeAudioAllowListPreferenceController(context, fragment));
        controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment));
        controllers.add(new BluetoothLeAudioHwOffloadPreferenceController(context, fragment));
        controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context));
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.development;

import static android.bluetooth.BluetoothStatusCodes.FEATURE_SUPPORTED;

import static com.android.settings.development.BluetoothLeAudioAllowListPreferenceController
        .LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

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;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

@RunWith(RobolectricTestRunner.class)
public class BluetoothLeAudioAllowListPreferenceControllerTest {

    @Mock
    private PreferenceScreen mPreferenceScreen;
    @Mock
    private DevelopmentSettingsDashboardFragment mFragment;

    @Mock
    private BluetoothAdapter mBluetoothAdapter;

    private Context mContext;
    private SwitchPreference mPreference;
    private BluetoothLeAudioPreferenceController mController;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        mPreference = new SwitchPreference(mContext);
        mController = spy(new BluetoothLeAudioPreferenceController(mContext, mFragment));
        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
            .thenReturn(mPreference);
        mController.mBluetoothAdapter = mBluetoothAdapter;
        mController.displayPreference(mPreferenceScreen);
        when(mBluetoothAdapter.isLeAudioSupported())
            .thenReturn(FEATURE_SUPPORTED);
    }

    @Test
    public void onRebootDialogConfirmedAsLeAudioAllowListDisabled_shouldSwitchStatus() {
        SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, Boolean.toString(false));
        mController.mChanged = true;

        mController.onRebootDialogConfirmed();
        final boolean mode = SystemProperties.getBoolean(
                LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
        assertThat(mode).isFalse();
    }


    @Test
    public void onRebootDialogConfirmedAsLeAudioAllowListEnabled_shouldSwitchStatus() {
        SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, Boolean.toString(true));
        mController.mChanged = true;

        mController.onRebootDialogConfirmed();
        final boolean status = SystemProperties.getBoolean(
                LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
        assertThat(status).isTrue();
    }

    @Test
    public void onRebootDialogCanceled_shouldNotSwitchStatus() {
        SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, Boolean.toString(false));
        mController.mChanged = true;

        mController.onRebootDialogCanceled();
        final boolean status = SystemProperties.getBoolean(
                LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
        assertThat(status).isFalse();
    }
}