1 /* 2 * Copyright 2024 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 import android.text.TextUtils; 26 27 import androidx.annotation.NonNull; 28 import androidx.annotation.Nullable; 29 import androidx.annotation.VisibleForTesting; 30 import androidx.preference.ListPreference; 31 import androidx.preference.Preference; 32 33 import com.android.settings.R; 34 import com.android.settings.core.PreferenceControllerMixin; 35 import com.android.settingslib.development.DeveloperOptionsPreferenceController; 36 37 38 /** 39 * Preference controller to control Bluetooth LE audio mode 40 */ 41 public class BluetoothLeAudioModePreferenceController 42 extends DeveloperOptionsPreferenceController 43 implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin { 44 45 private static final String PREFERENCE_KEY = "bluetooth_leaudio_mode"; 46 47 static final String LE_AUDIO_DYNAMIC_SWITCHER_MODE_PROPERTY = 48 "persist.bluetooth.leaudio_dynamic_switcher.mode"; 49 50 @Nullable private final DevelopmentSettingsDashboardFragment mFragment; 51 52 private final String[] mListValues; 53 private final String[] mListSummaries; 54 @VisibleForTesting 55 @Nullable String mNewMode; 56 @VisibleForTesting 57 BluetoothAdapter mBluetoothAdapter; 58 59 boolean mChanged = false; 60 BluetoothLeAudioModePreferenceController(@onNull Context context, @Nullable DevelopmentSettingsDashboardFragment fragment)61 public BluetoothLeAudioModePreferenceController(@NonNull Context context, 62 @Nullable DevelopmentSettingsDashboardFragment fragment) { 63 super(context); 64 mFragment = fragment; 65 mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); 66 67 mListValues = context.getResources().getStringArray(R.array.bluetooth_leaudio_mode_values); 68 mListSummaries = context.getResources().getStringArray(R.array.bluetooth_leaudio_mode); 69 } 70 71 @Override getPreferenceKey()72 @NonNull public String getPreferenceKey() { 73 return PREFERENCE_KEY; 74 } 75 76 @Override isAvailable()77 public boolean isAvailable() { 78 return BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false); 79 } 80 81 @Override onPreferenceChange(@onNull Preference preference, Object newValue)82 public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { 83 if (mFragment == null) { 84 return false; 85 } 86 87 BluetoothRebootDialog.show(mFragment); 88 mChanged = true; 89 mNewMode = newValue.toString(); 90 return false; 91 } 92 93 @Override updateState(@onNull Preference preference)94 public void updateState(@NonNull Preference preference) { 95 if (mBluetoothAdapter == null) { 96 return; 97 } 98 99 String currentValue; 100 if (mBluetoothAdapter.isLeAudioBroadcastSourceSupported() 101 == BluetoothStatusCodes.FEATURE_SUPPORTED) { 102 currentValue = "broadcast"; 103 } else if (mBluetoothAdapter.isLeAudioSupported() 104 == BluetoothStatusCodes.FEATURE_SUPPORTED) { 105 currentValue = "unicast"; 106 } else { 107 currentValue = "disabled"; 108 } 109 110 int index = 0; 111 for (int i = 0; i < mListValues.length; i++) { 112 if (TextUtils.equals(currentValue, mListValues[i])) { 113 index = i; 114 break; 115 } 116 } 117 118 final ListPreference listPreference = (ListPreference) preference; 119 listPreference.setValue(mListValues[index]); 120 listPreference.setSummary(mListSummaries[index]); 121 122 if (!mBluetoothAdapter.isEnabled()) { 123 listPreference.setEnabled(false); 124 return; 125 } 126 } 127 128 /** 129 * Called when the RebootDialog confirm is clicked. 130 */ onRebootDialogConfirmed()131 public void onRebootDialogConfirmed() { 132 if (!mChanged) { 133 return; 134 } 135 SystemProperties.set(LE_AUDIO_DYNAMIC_SWITCHER_MODE_PROPERTY, mNewMode); 136 } 137 138 /** 139 * Called when the RebootDialog cancel is clicked. 140 */ onRebootDialogCanceled()141 public void onRebootDialogCanceled() { 142 mChanged = false; 143 } 144 } 145