• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.development;
18 
19 import android.bluetooth.BluetoothAdapter;
20 import android.bluetooth.BluetoothManager;
21 import android.bluetooth.BluetoothStatusCodes;
22 import android.content.Context;
23 import android.os.SystemProperties;
24 import android.sysprop.BluetoothProperties;
25 
26 import androidx.annotation.VisibleForTesting;
27 import androidx.preference.Preference;
28 import androidx.preference.TwoStatePreference;
29 
30 import com.android.settings.core.PreferenceControllerMixin;
31 import com.android.settingslib.development.DeveloperOptionsPreferenceController;
32 
33 /**
34  * Preference controller to control Bluetooth LE audio feature
35  */
36 public class BluetoothLeAudioAllowListPreferenceController
37         extends DeveloperOptionsPreferenceController
38         implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
39 
40     private static final String PREFERENCE_KEY = "bluetooth_bypass_leaudio_allowlist";
41 
42     static final String LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY =
43             "ro.bluetooth.leaudio.le_audio_connection_by_default";
44     @VisibleForTesting
45     static final String BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY =
46             "persist.bluetooth.leaudio.bypass_allow_list";
47 
48     @VisibleForTesting
49     BluetoothAdapter mBluetoothAdapter;
50     @VisibleForTesting boolean mLeAudioConnectionByDefault;
51 
BluetoothLeAudioAllowListPreferenceController(Context context)52     public BluetoothLeAudioAllowListPreferenceController(Context context) {
53         super(context);
54         mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
55         mLeAudioConnectionByDefault =
56                 SystemProperties.getBoolean(LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY, true);
57     }
58 
59     @Override
getPreferenceKey()60     public String getPreferenceKey() {
61         return PREFERENCE_KEY;
62     }
63 
64     @Override
isAvailable()65     public boolean isAvailable() {
66         return BluetoothProperties.isProfileBapUnicastClientEnabled().orElse(false)
67                 && mLeAudioConnectionByDefault;
68     }
69 
70     @Override
onPreferenceChange(Preference preference, Object newValue)71     public boolean onPreferenceChange(Preference preference, Object newValue) {
72         final boolean isBypassed = (Boolean) newValue;
73         SystemProperties.set(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY,
74                 isBypassed ? "true" : "false");
75         return true;
76     }
77 
78     @Override
updateState(Preference preference)79     public void updateState(Preference preference) {
80         if (mBluetoothAdapter == null) {
81             mPreference.setEnabled(false);
82             return;
83         }
84 
85         final boolean isLeAudioSupported =
86                 (mBluetoothAdapter.isLeAudioSupported() == BluetoothStatusCodes.FEATURE_SUPPORTED);
87         if (!isLeAudioSupported) {
88             mPreference.setEnabled(false);
89             ((TwoStatePreference) mPreference).setChecked(false);
90             return;
91         }
92 
93         mPreference.setEnabled(true);
94         final boolean isLeAudioAllowlistBypassed =
95                 SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, false);
96         ((TwoStatePreference) mPreference).setChecked(isLeAudioAllowlistBypassed);
97     }
98 
99     @Override
onDeveloperOptionsSwitchDisabled()100     protected void onDeveloperOptionsSwitchDisabled() {
101         super.onDeveloperOptionsSwitchDisabled();
102         final boolean isBypassed =
103                 SystemProperties.getBoolean(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, false);
104         if (isBypassed) {
105             SystemProperties.set(BYPASS_LE_AUDIO_ALLOWLIST_PROPERTY, Boolean.toString(false));
106             ((TwoStatePreference) mPreference).setChecked(false);
107         }
108     }
109 }
110