From 97b113a6609a65e85eb93c6e0b0ce50f8f62862b Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Wed, 21 Aug 2024 15:48:23 +0000 Subject: [PATCH] bluetooth: Refactor BT Audio Codec list * Show only selectable codecs to the user * Removed redundant 'abstract' layer * Disable codec selection when BluetoothA2dp, active device unavailable or HD Audio disabled. Bug: 329809288 Bug: 346490998 Flag: EXEMPT - refactor Test: atest SettingsRoboTests:com.android.settings.development.bluetooth.BluetoothCodecListPreferenceControllerTest Merged-In: I56ebfeaf2cfa22ec253db897d7b7e96d1f8eee61 Change-Id: I23714715d9257479f5eac1a172ba1804da7e64e3 --- .../DevelopmentSettingsDashboardFragment.java | 5 +- ...ractBluetoothListPreferenceController.java | 261 ----------------- ...luetoothCodecListPreferenceController.java | 270 ++++++++++++++---- ...BluetoothListPreferenceControllerTest.java | 240 ---------------- ...oothCodecListPreferenceControllerTest.java | 238 +++++++++++++-- 5 files changed, 428 insertions(+), 586 deletions(-) delete mode 100644 src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceControllerTest.java diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 58979655e29..d65a231d397 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -62,7 +62,6 @@ import com.android.settings.development.autofill.AutofillCategoryController; import com.android.settings.development.autofill.AutofillLoggingLevelPreferenceController; import com.android.settings.development.autofill.AutofillResetOptionsPreferenceController; import com.android.settings.development.bluetooth.AbstractBluetoothDialogPreferenceController; -import com.android.settings.development.bluetooth.AbstractBluetoothListPreferenceController; import com.android.settings.development.bluetooth.AbstractBluetoothPreferenceController; import com.android.settings.development.bluetooth.BluetoothBitPerSampleDialogPreferenceController; import com.android.settings.development.bluetooth.BluetoothChannelModeDialogPreferenceController; @@ -811,8 +810,8 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra ((AbstractBluetoothDialogPreferenceController) controller).onHDAudioEnabled( enabled); } - if (controller instanceof AbstractBluetoothListPreferenceController) { - ((AbstractBluetoothListPreferenceController) controller).onHDAudioEnabled(enabled); + if (controller instanceof BluetoothCodecListPreferenceController) { + ((BluetoothCodecListPreferenceController) controller).onHDAudioEnabled(enabled); } } } diff --git a/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceController.java b/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceController.java deleted file mode 100644 index 362a5cdde99..00000000000 --- a/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceController.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2023 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.bluetooth; - -import static android.bluetooth.BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - -import android.bluetooth.BluetoothA2dp; -import android.bluetooth.BluetoothCodecConfig; -import android.bluetooth.BluetoothCodecStatus; -import android.bluetooth.BluetoothDevice; -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.development.BluetoothA2dpConfigStore; -import com.android.settingslib.core.lifecycle.Lifecycle; - -import java.util.List; - -/** Abstract class for Bluetooth A2DP config list controller in developer option. */ -public abstract class AbstractBluetoothListPreferenceController - extends AbstractBluetoothPreferenceController - implements Preference.OnPreferenceChangeListener { - - private static final String TAG = "AbstrBtListPrefCtrl"; - - protected static final int DEFAULT_VALUE_INT = 1000; - - @Nullable protected ListPreference mListPreference; - - protected String mDefaultEntry; - protected String mDefaultValue; - - @Nullable protected final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - - public AbstractBluetoothListPreferenceController( - @NonNull Context context, - @Nullable Lifecycle lifecycle, - @Nullable BluetoothA2dpConfigStore store) { - super(context, lifecycle, store); - - mDefaultEntry = mContext.getString(R.string.bluetooth_audio_codec_default_selection); - mDefaultValue = String.valueOf(DEFAULT_VALUE_INT); - - mBluetoothA2dpConfigStore = store; - } - - @Override - public void displayPreference(@NonNull PreferenceScreen screen) { - super.displayPreference(screen); - mListPreference = screen.findPreference(getPreferenceKey()); - } - - @Override - public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) { - Log.d(TAG, "onPreferenceChange: newValue=" + (String) newValue); - if (mListPreference == null) { - Log.e(TAG, "onPreferenceChange: List preference is null"); - return false; - } - updateState(mListPreference); - return true; - } - - @Override - public void updateState(@Nullable Preference preference) { - setupDefaultListPreference(); - } - - @Override - public void onBluetoothServiceConnected(@NonNull BluetoothA2dp bluetoothA2dp) { - super.onBluetoothServiceConnected(bluetoothA2dp); - initConfigStore(); - } - - @Override - protected void onDeveloperOptionsSwitchDisabled() { - super.onDeveloperOptionsSwitchDisabled(); - Log.d(TAG, "onDeveloperOptionsSwitchDisabled"); - if (mListPreference == null) { - Log.e(TAG, "onDeveloperOptionsSwitchDisabled: List preference is null"); - return; - } - updateState(mListPreference); - } - - /** - * Method to notify controller when the HD audio(optional codec) state is changed. - * - * @param enabled Is {@code true} when the setting is enabled. - */ - public void onHDAudioEnabled(boolean enabled) {} - - /** - * Updates the new value to the {@link BluetoothA2dpConfigStore}. - * - * @param entryValue the new setting entry value - */ - protected abstract void writeConfigurationValues(String entryValue); - - /** - * Gets the current bluetooth codec status. - * - * @return {@link BluetoothCodecStatus}. - */ - @Nullable - protected BluetoothCodecStatus getBluetoothCodecStatus() { - final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; - if (bluetoothA2dp == null) { - Log.e( - TAG, - "getBluetoothCodecStatus: Unable to get codec status. Bluetooth A2dp is null."); - return null; - } - final BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null) { - Log.e(TAG, "getBluetoothCodecStatus: Unable to get codec status. No active device."); - return null; - } - final BluetoothCodecStatus codecStatus = bluetoothA2dp.getCodecStatus(activeDevice); - if (codecStatus == null) { - Log.e(TAG, "getBluetoothCodecStatus: Codec status is null"); - return null; - } - return codecStatus; - } - - /** - * Gets the current bluetooth codec config. - * - * @return {@link BluetoothCodecConfig}. - */ - @Nullable - protected BluetoothCodecConfig getCurrentCodecConfig() { - final BluetoothCodecStatus codecStatus = getBluetoothCodecStatus(); - if (codecStatus == null) { - Log.e( - TAG, - "getCurrentCodecConfig: Unable to get current codec config. Codec status is" - + " null"); - return null; - } - - return codecStatus.getCodecConfig(); - } - - /** - * Sets the {@link ListPreference}. This method adds the default entry and the entry value - * automatically. - * - * @param entries list of String entries for the {@link ListPreference}. - * @param entryValues list of String entry values for the {@link ListPreference}. - * @param selectedEntry currently selected entry. - * @param selectedValue currently selected entry value. - */ - protected void setupListPreference( - List entries, - List entryValues, - String selectedEntry, - String selectedValue) { - if (entries.size() != entryValues.size()) { - Log.e( - TAG, - ("setupListPreference: size of entries: " + entries.size()) - + (", size of entryValues" + entryValues.size())); - setupDefaultListPreference(); - return; - } - if (entries.isEmpty() || entryValues.isEmpty()) { - Log.e(TAG, "setupListPreference: entries or entryValues empty"); - setupDefaultListPreference(); - return; - } - entries.add(0, mDefaultEntry); - entryValues.add(0, mDefaultValue); - - if (mListPreference == null) { - Log.e(TAG, "setupListPreference: List preference is null"); - return; - } - mListPreference.setEntries(entries.toArray(new String[entries.size()])); - mListPreference.setEntryValues(entryValues.toArray(new String[entryValues.size()])); - mListPreference.setValue(selectedValue); - mListPreference.setSummary(selectedEntry); - } - - /** - * Check HD Audio enabled. - * - * @return true if HD Audio is enabled. - */ - protected boolean isHDAudioEnabled() { - final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; - if (bluetoothA2dp == null) { - Log.e(TAG, "isHDAudioEnabled: Unable to get codec status. BluetoothA2dp is null."); - return false; - } - BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null) { - Log.e(TAG, "isHDAudioEnabled: Unable to get codec status. No active device."); - return false; - } - return (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice) - == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - } - - private void setupDefaultListPreference() { - Log.d( - TAG, - "setupDefaultListPreference: mDefaultEntry=" - + mDefaultEntry - + ", mDefaultValue=" - + mDefaultValue); - if (mListPreference == null) { - Log.e(TAG, "setupListPreference: List preference is null"); - return; - } - mListPreference.setEntries(new String[] {mDefaultEntry}); - mListPreference.setEntryValues(new String[] {mDefaultValue}); - mListPreference.setValue(mDefaultValue); - mListPreference.setSummary(mDefaultEntry); - } - - private void initConfigStore() { - final BluetoothCodecConfig config = getCurrentCodecConfig(); - if (config == null) { - Log.e(TAG, "initConfigStore: Current codec config is null."); - return; - } - if (mBluetoothA2dpConfigStore == null) { - Log.e(TAG, "initConfigStore: Bluetooth A2dp Config Store is null."); - return; - } - mBluetoothA2dpConfigStore.setCodecType(config.getExtendedCodecType()); - mBluetoothA2dpConfigStore.setSampleRate(config.getSampleRate()); - mBluetoothA2dpConfigStore.setBitsPerSample(config.getBitsPerSample()); - mBluetoothA2dpConfigStore.setChannelMode(config.getChannelMode()); - mBluetoothA2dpConfigStore.setCodecPriority(CODEC_PRIORITY_HIGHEST); - mBluetoothA2dpConfigStore.setCodecSpecific1Value(config.getCodecSpecific1()); - } -} diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java index 9808807b077..72da5053a69 100644 --- a/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java +++ b/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java @@ -26,9 +26,11 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; +import com.android.internal.annotations.VisibleForTesting; import com.android.settings.development.BluetoothA2dpConfigStore; import com.android.settings.development.Flags; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -38,13 +40,15 @@ import java.util.Collection; import java.util.List; /** List preference controller to set the Bluetooth A2DP codec */ -public class BluetoothCodecListPreferenceController - extends AbstractBluetoothListPreferenceController { +public class BluetoothCodecListPreferenceController extends AbstractBluetoothPreferenceController + implements Preference.OnPreferenceChangeListener { private static final String KEY = "bluetooth_audio_codec_settings_list"; private static final String TAG = "BtExtCodecCtr"; @Nullable private final Callback mCallback; + @Nullable protected final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; + @Nullable protected ListPreference mListPreference; public BluetoothCodecListPreferenceController( @NonNull Context context, @@ -53,6 +57,7 @@ public class BluetoothCodecListPreferenceController @Nullable Callback callback) { super(context, lifecycle, store); mCallback = callback; + mBluetoothA2dpConfigStore = store; } @Override @@ -79,32 +84,38 @@ public class BluetoothCodecListPreferenceController return false; } + if (mListPreference == null) { + Log.e(TAG, "onPreferenceChange: List preference is null"); + return false; + } + Log.d(TAG, "onPreferenceChange: newValue=" + (String) newValue); final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; if (bluetoothA2dp == null) { Log.e(TAG, "onPreferenceChange: bluetoothA2dp is null"); + setListPreferenceEnabled(false); return false; } - writeConfigurationValues((String) newValue); + if (!writeConfigurationValues((String) newValue)) { + Log.e(TAG, "onPreferenceChange: Configuration failed"); + return false; + } if (mBluetoothA2dpConfigStore == null) { Log.e(TAG, "onPreferenceChange: Bluetooth A2dp Config Store is null"); return false; } - BluetoothCodecConfig codecConfig; - if (Flags.a2dpOffloadCodecExtensibilitySettings()) { - codecConfig = mBluetoothA2dpConfigStore.createCodecConfigFromCodecType(); - } else { - codecConfig = mBluetoothA2dpConfigStore.createCodecConfig(); - } final BluetoothDevice activeDevice = getA2dpActiveDevice(); if (activeDevice == null) { Log.e(TAG, "onPreferenceChange: active device is null"); + setListPreferenceEnabled(false); return false; } + BluetoothCodecConfig codecConfig = + mBluetoothA2dpConfigStore.createCodecConfigFromCodecType(); Log.d(TAG, "onPreferenceChange: setCodecConfigPreference: " + codecConfig.toString()); bluetoothA2dp.setCodecConfigPreference(activeDevice, codecConfig); if (mCallback != null) { @@ -121,64 +132,74 @@ public class BluetoothCodecListPreferenceController return; } + if (!isHDAudioEnabled()) { + Log.d(TAG, "updateState: HD Audio is disabled"); + setListPreferenceEnabled(false); + return; + } + + final BluetoothCodecStatus codecStatus = getBluetoothCodecStatus(); + if (codecStatus == null) { + Log.e(TAG, "updateState: Bluetooth Codec Status is null"); + return; + } + + final BluetoothCodecConfig currentCodecConfig = codecStatus.getCodecConfig(); + if (currentCodecConfig == null) { + Log.e(TAG, "updateState: currentCodecConfig is null"); + return; + } + final List codecIds = new ArrayList<>(); final List labels = new ArrayList<>(); - String selectedCodecId = mDefaultValue; - String selectedLabel = mDefaultEntry; - - if (isHDAudioEnabled()) { - final BluetoothCodecStatus codecStatus = getBluetoothCodecStatus(); - if (codecStatus == null) { - Log.e(TAG, "updateState: Bluetooth Codec Status is null"); - return; + String selectedCodecId = null; + String selectedLabel = null; + final List codecConfigs = + codecStatus.getCodecsSelectableCapabilities(); + for (BluetoothCodecConfig config : codecConfigs) { + BluetoothCodecType codecType = config.getExtendedCodecType(); + if (codecType == null) { + Log.e(TAG, "codec type for config:" + config + " is null"); + continue; } - - final BluetoothCodecConfig currentCodecConfig = codecStatus.getCodecConfig(); - if (currentCodecConfig == null) { - Log.e(TAG, "updateState: currentCodecConfig is null"); - return; + labels.add(codecType.getCodecName()); + codecIds.add(String.valueOf(codecType.getCodecId())); + if (currentCodecConfig != null + && currentCodecConfig.getExtendedCodecType().equals(codecType)) { + selectedCodecId = codecIds.get(codecIds.size() - 1); + selectedLabel = labels.get(labels.size() - 1); + Log.d( + TAG, + "updateState: Selecting codec: " + + selectedLabel + + ", id: " + + selectedCodecId); } - - final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; - if (bluetoothA2dp == null) { - Log.e(TAG, "updateState: bluetoothA2dp is null"); - return; - } - - final Collection codecTypes = - bluetoothA2dp.getSupportedCodecTypes(); - for (BluetoothCodecType codecType : codecTypes) { - labels.add(codecType.getCodecName()); - codecIds.add(String.valueOf(codecType.getCodecId())); - if (currentCodecConfig != null - && currentCodecConfig.getExtendedCodecType().equals(codecType)) { - selectedCodecId = codecIds.get(codecIds.size() - 1); - selectedLabel = labels.get(labels.size() - 1); - Log.d( - TAG, - "updateState: Current config: " - + selectedLabel - + ", id: " - + selectedCodecId); - } - } - - setupListPreference(labels, codecIds, selectedLabel, selectedCodecId); } + setupListPreference(labels, codecIds, selectedLabel, selectedCodecId); } @Override + public void onBluetoothServiceConnected(@NonNull BluetoothA2dp bluetoothA2dp) { + super.onBluetoothServiceConnected(bluetoothA2dp); + initConfigStore(); + } + public void onHDAudioEnabled(boolean enabled) { Log.d(TAG, "onHDAudioEnabled: enabled=" + enabled); if (mListPreference == null) { Log.e(TAG, "onHDAudioEnabled: List preference is null"); return; } - mListPreference.setEnabled(enabled); + setListPreferenceEnabled(enabled); + if (!enabled) { + mListPreference.setValue(null); + mListPreference.setSummary(null); + } } - @Override - protected void writeConfigurationValues(String entryValue) { + @VisibleForTesting + boolean writeConfigurationValues(String entryValue) { long codecIdValue = getCodecIdFromEntryValue(entryValue); BluetoothCodecType selectedCodecType = null; BluetoothCodecConfig selectedCodecConfig = null; @@ -186,7 +207,7 @@ public class BluetoothCodecListPreferenceController final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; if (bluetoothA2dp == null) { Log.e(TAG, "writeConfigurationValues: bluetoothA2dp is null"); - return; + return false; } final Collection codecTypes = bluetoothA2dp.getSupportedCodecTypes(); @@ -202,14 +223,14 @@ public class BluetoothCodecListPreferenceController "writeConfigurationValues: No selectable codec ID: " + codecIdValue + " found. Unable to change codec"); - return; + return false; } Log.d(TAG, "writeConfigurationValues: Selected codec: " + selectedCodecType.toString()); final BluetoothCodecStatus codecStatus = getBluetoothCodecStatus(); if (codecStatus == null) { Log.e(TAG, "writeConfigurationValues: Bluetooth Codec Status is null"); - return; + return false; } final List codecConfigs = @@ -218,8 +239,9 @@ public class BluetoothCodecListPreferenceController BluetoothCodecType codecType = config.getExtendedCodecType(); if (codecType == null) { Log.e(TAG, "codec type for config:" + config + " is null"); + continue; } - if (codecType != null && codecType.equals(selectedCodecType)) { + if (codecType.equals(selectedCodecType)) { selectedCodecConfig = config; } } @@ -229,12 +251,12 @@ public class BluetoothCodecListPreferenceController TAG, "writeConfigurationValues: No selectable codec config for codec: " + selectedCodecType.toString()); - return; + return false; } if (mBluetoothA2dpConfigStore == null) { Log.e(TAG, "writeConfigurationValues: Bluetooth A2dp Config Store is null"); - return; + return false; } mBluetoothA2dpConfigStore.setCodecType(selectedCodecType); @@ -248,13 +270,145 @@ public class BluetoothCodecListPreferenceController mBluetoothA2dpConfigStore.setChannelMode( AbstractBluetoothDialogPreferenceController.getHighestChannelMode( selectedCodecConfig)); + return true; } private long getCodecIdFromEntryValue(String entryValue) { long codecType = BluetoothCodecType.CODEC_ID_SBC; - if (entryValue.isEmpty() || Long.valueOf(entryValue) == DEFAULT_VALUE_INT) { + if (entryValue.isEmpty()) { return codecType; } return Long.valueOf(entryValue); } + + private void setListPreferenceEnabled(boolean enable) { + if (mListPreference != null) { + mListPreference.setEnabled(enable); + } + } + + @Nullable + @VisibleForTesting + BluetoothCodecStatus getBluetoothCodecStatus() { + final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; + if (bluetoothA2dp == null) { + Log.e( + TAG, + "getBluetoothCodecStatus: Unable to get codec status. Bluetooth A2dp is null."); + return null; + } + final BluetoothDevice activeDevice = getA2dpActiveDevice(); + if (activeDevice == null) { + Log.e(TAG, "getBluetoothCodecStatus: Unable to get codec status. No active device."); + return null; + } + final BluetoothCodecStatus codecStatus = bluetoothA2dp.getCodecStatus(activeDevice); + if (codecStatus == null) { + Log.e(TAG, "getBluetoothCodecStatus: Codec status is null"); + return null; + } + return codecStatus; + } + + @Nullable + @VisibleForTesting + BluetoothCodecConfig getCurrentCodecConfig() { + final BluetoothCodecStatus codecStatus = getBluetoothCodecStatus(); + if (codecStatus == null) { + Log.e( + TAG, + "getCurrentCodecConfig: Unable to get current codec config. Codec status is" + + " null"); + return null; + } + + return codecStatus.getCodecConfig(); + } + + @VisibleForTesting + boolean isHDAudioEnabled() { + final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; + if (bluetoothA2dp == null) { + Log.e(TAG, "isHDAudioEnabled: Unable to get codec status. BluetoothA2dp is null."); + return false; + } + BluetoothDevice activeDevice = getA2dpActiveDevice(); + if (activeDevice == null) { + Log.e(TAG, "isHDAudioEnabled: Unable to get codec status. No active device."); + return false; + } + return (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice) + == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); + } + + @VisibleForTesting + void initConfigStore() { + final BluetoothCodecConfig config = getCurrentCodecConfig(); + if (config == null) { + Log.e(TAG, "initConfigStore: Current codec config is null."); + return; + } + if (mBluetoothA2dpConfigStore == null) { + Log.e(TAG, "initConfigStore: Bluetooth A2dp Config Store is null."); + return; + } + mBluetoothA2dpConfigStore.setCodecType(config.getExtendedCodecType()); + mBluetoothA2dpConfigStore.setSampleRate(config.getSampleRate()); + mBluetoothA2dpConfigStore.setBitsPerSample(config.getBitsPerSample()); + mBluetoothA2dpConfigStore.setChannelMode(config.getChannelMode()); + mBluetoothA2dpConfigStore.setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST); + mBluetoothA2dpConfigStore.setCodecSpecific1Value(config.getCodecSpecific1()); + } + + @VisibleForTesting + void setupDefaultListPreference() { + Log.d(TAG, "setupDefaultListPreference"); + if (mListPreference == null) { + Log.e(TAG, "setupDefaultListPreference: List preference is null"); + return; + } + mListPreference.setValue(null); + mListPreference.setSummary(null); + setListPreferenceEnabled(false); + } + + /** + * Sets the {@link ListPreference}. + * + * @param entries list of String entries for the {@link ListPreference}. + * @param entryValues list of String entry values for the {@link ListPreference}. + * @param selectedEntry currently selected entry. + * @param selectedValue currently selected entry value. + */ + @VisibleForTesting + void setupListPreference( + List entries, + List entryValues, + @Nullable String selectedEntry, + @Nullable String selectedValue) { + if (mListPreference == null) { + Log.e(TAG, "setupListPreference: List preference is null"); + return; + } + + if (entries.size() != entryValues.size()) { + Log.e( + TAG, + ("setupListPreference: size of entries: " + entries.size()) + + (", size of entryValues" + entryValues.size())); + setupDefaultListPreference(); + return; + } + if (entries.isEmpty() || entryValues.isEmpty()) { + Log.e(TAG, "setupListPreference: entries or entryValues empty"); + setupDefaultListPreference(); + return; + } + + mListPreference.setEntries(entries.toArray(new String[entries.size()])); + mListPreference.setEntryValues(entryValues.toArray(new String[entryValues.size()])); + mListPreference.setValue(selectedValue); + mListPreference.setSummary(selectedEntry); + setListPreferenceEnabled(true); + } } diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceControllerTest.java deleted file mode 100644 index 8abc633f84d..00000000000 --- a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothListPreferenceControllerTest.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2023 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.bluetooth; - -import static android.bluetooth.BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.bluetooth.BluetoothA2dp; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothCodecConfig; -import android.bluetooth.BluetoothCodecStatus; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothProfile; -import android.content.Context; - -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.ListPreference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.development.BluetoothA2dpConfigStore; -import com.android.settingslib.core.lifecycle.Lifecycle; - -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; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class AbstractBluetoothListPreferenceControllerTest { - - private static final String DEVICE_ADDRESS = "00:11:22:33:44:55"; - - private static String DEFAULT_ENTRY; - private static final String DEFAULT_ENTRY_VALUE = "1000"; - - @Mock private BluetoothA2dp mBluetoothA2dp; - @Mock private BluetoothAdapter mBluetoothAdapter; - @Mock private PreferenceScreen mScreen; - - private AbstractBluetoothListPreferenceController mController; - private ListPreference mPreference; - private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - private BluetoothCodecStatus mCodecStatus; - private BluetoothCodecConfig mCodecConfigAAC; - private BluetoothCodecConfig mCodecConfigSBC; - private BluetoothCodecConfig[] mCodecConfigs = new BluetoothCodecConfig[2]; - private BluetoothDevice mActiveDevice; - private Context mContext; - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); - mBluetoothA2dpConfigStore = spy(new BluetoothA2dpConfigStore()); - mActiveDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(DEVICE_ADDRESS); - mController = - spy( - new AbstractBluetoothListPreferenceControllerImpl( - mContext, mLifecycle, mBluetoothA2dpConfigStore)); - mController.mBluetoothAdapter = mBluetoothAdapter; - mPreference = spy(new ListPreference(mContext)); - - mCodecConfigAAC = - new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) - .build(); - mCodecConfigSBC = - new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) - .build(); - mCodecConfigs[0] = mCodecConfigAAC; - mCodecConfigs[1] = mCodecConfigSBC; - - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - mController.displayPreference(mScreen); - when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.A2DP))) - .thenReturn(Arrays.asList(mActiveDevice)); - - DEFAULT_ENTRY = mContext.getString(R.string.bluetooth_audio_codec_default_selection); - } - - private void verifySetupDefaultListPreference() { - List entries = new ArrayList<>(1); - entries.add(DEFAULT_ENTRY); - List entryValues = new ArrayList<>(1); - entryValues.add(DEFAULT_ENTRY_VALUE); - - verify(mPreference).setEntries(entries.toArray(new String[entries.size()])); - verify(mPreference).setEntryValues(entryValues.toArray(new String[entryValues.size()])); - verify(mPreference).setValue(DEFAULT_ENTRY_VALUE); - verify(mPreference).setSummary(DEFAULT_ENTRY); - } - - @Test - public void onPreferenceChange_shouldSetupDefaultListPreference() { - mController.onPreferenceChange(mPreference, "" /* new value */); - verifySetupDefaultListPreference(); - } - - @Test - public void setupListPreference_wrongSize_shouldSetupDefaultListPreference() { - List entries = new ArrayList<>(1); - entries.add(DEFAULT_ENTRY); - List entryValues = new ArrayList<>(2); - entryValues.add(DEFAULT_ENTRY_VALUE); - entryValues.add(DEFAULT_ENTRY_VALUE); - - mController.setupListPreference(entries, entryValues, "", ""); - verifySetupDefaultListPreference(); - } - - @Test - public void setupListPreference_listEmpty_shouldSetupDefaultListPreference() { - List entries = new ArrayList<>(1); - entries.add(DEFAULT_ENTRY); - List entryValues = new ArrayList<>(); - - mController.setupListPreference(entries, entryValues, "", ""); - verifySetupDefaultListPreference(); - } - - @Test - public void getBluetoothCodecStatus_errorChecking() { - mController.onBluetoothServiceConnected(null); - assertThat(mController.getBluetoothCodecStatus()).isNull(); - - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(null); - assertThat(mController.getBluetoothCodecStatus()).isNull(); - } - - @Test - public void getCurrentCodecConfig_errorChecking() { - mController.onBluetoothServiceConnected(null); - assertThat(mController.getCurrentCodecConfig()).isNull(); - - mController.onBluetoothServiceConnected(mBluetoothA2dp); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(null); - assertThat(mController.getCurrentCodecConfig()).isNull(); - } - - @Test - public void getCurrentCodecConfig_verifyConfig() { - mCodecStatus = new BluetoothCodecStatus.Builder().setCodecConfig(mCodecConfigAAC).build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - assertThat(mController.getCurrentCodecConfig()).isEqualTo(mCodecConfigAAC); - } - - @Test - public void isHDAudioEnabled_errorChecking() { - mController.onBluetoothServiceConnected(null); - assertFalse(mController.isHDAudioEnabled()); - - mController.onBluetoothServiceConnected(mBluetoothA2dp); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) - .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); - assertFalse(mController.isHDAudioEnabled()); - } - - @Test - public void isHDAudioEnabled_verifyEnabled() { - mController.onBluetoothServiceConnected(mBluetoothA2dp); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) - .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - assertTrue(mController.isHDAudioEnabled()); - } - - @Test - public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() { - mCodecStatus = - new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigAAC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getExtendedCodecType()); - verify(mBluetoothA2dpConfigStore).setSampleRate(mCodecConfigAAC.getSampleRate()); - verify(mBluetoothA2dpConfigStore).setBitsPerSample(mCodecConfigAAC.getBitsPerSample()); - verify(mBluetoothA2dpConfigStore).setChannelMode(mCodecConfigAAC.getChannelMode()); - verify(mBluetoothA2dpConfigStore).setCodecPriority(CODEC_PRIORITY_HIGHEST); - verify(mBluetoothA2dpConfigStore) - .setCodecSpecific1Value(mCodecConfigAAC.getCodecSpecific1()); - } - - private static class AbstractBluetoothListPreferenceControllerImpl - extends AbstractBluetoothListPreferenceController { - - private AbstractBluetoothListPreferenceControllerImpl( - Context context, Lifecycle lifecycle, BluetoothA2dpConfigStore store) { - super(context, lifecycle, store); - } - - @Override - public String getPreferenceKey() { - return "KEY"; - } - - @Override - protected void writeConfigurationValues(String entryValue) {} - } -} diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java index fab867fa0cf..4ac5dff1eef 100644 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java @@ -18,12 +18,12 @@ package com.android.settings.development.bluetooth; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -35,7 +35,7 @@ import android.bluetooth.BluetoothCodecType; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; -import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.annotations.EnableFlags; import androidx.lifecycle.LifecycleOwner; import androidx.preference.ListPreference; @@ -89,6 +89,9 @@ public class BluetoothCodecListPreferenceControllerTest { private LifecycleOwner mLifecycleOwner; private Lifecycle mLifecycle; + private static String TEST_ENTRY = "TEST_ENTRY"; + private static final String TEST_ENTRY_VALUE = "1000"; + @Before public void setup() { MockitoAnnotations.initMocks(this); @@ -181,21 +184,10 @@ public class BluetoothCodecListPreferenceControllerTest { when(mBluetoothA2dp.getSupportedCodecTypes()).thenReturn(mCodecTypes); } - @Test - public void writeConfigurationValues_selectDefault() { - mCodecStatus = - new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigSBC) - .setCodecsSelectableCapabilities(mCodecConfigs) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) - .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.writeConfigurationValues(String.valueOf(mController.DEFAULT_VALUE_INT)); - verify(mBluetoothA2dpConfigStore, times(2)).setCodecType(mCodecTypeSBC); + private void verifySetupDefaultListPreference() { + assertTrue(mPreference.getValue() == null); + assertTrue(mPreference.getSummary() == null); + assertTrue(mPreference.isEnabled() == false); } @Test @@ -208,19 +200,24 @@ public class BluetoothCodecListPreferenceControllerTest { when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); mController.onBluetoothServiceConnected(mBluetoothA2dp); - mController.writeConfigurationValues(String.valueOf(mCodecTypeSBC.getCodecId())); + assertTrue( + mController.writeConfigurationValues(String.valueOf(mCodecTypeSBC.getCodecId()))); verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType(mCodecTypeSBC); - mController.writeConfigurationValues(String.valueOf(mCodecTypeAAC.getCodecId())); + assertTrue( + mController.writeConfigurationValues(String.valueOf(mCodecTypeAAC.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAAC); - mController.writeConfigurationValues(String.valueOf(mCodecTypeAPTX.getCodecId())); + assertTrue( + mController.writeConfigurationValues(String.valueOf(mCodecTypeAPTX.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTX); - mController.writeConfigurationValues(String.valueOf(mCodecTypeLDAC.getCodecId())); + assertTrue( + mController.writeConfigurationValues(String.valueOf(mCodecTypeLDAC.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeLDAC); - mController.writeConfigurationValues(String.valueOf(mCodecTypeOPUS.getCodecId())); + assertTrue( + mController.writeConfigurationValues(String.valueOf(mCodecTypeOPUS.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeOPUS); } @@ -233,7 +230,8 @@ public class BluetoothCodecListPreferenceControllerTest { .build(); when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); mController.onBluetoothServiceConnected(mBluetoothA2dp); - mController.writeConfigurationValues(String.valueOf(mCodecTypeAAC.getCodecId())); + assertTrue( + mController.writeConfigurationValues(String.valueOf(mCodecTypeAAC.getCodecId()))); verify(mBluetoothA2dpConfigStore, atLeastOnce()) .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST); @@ -246,12 +244,112 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) + @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onPreferenceChange_notifyPreference() { assertFalse( mController.onPreferenceChange( mPreference, String.valueOf(mCodecTypeAAC.getCodecId()))); + assertFalse(mPreference.isEnabled()); + when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) + .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAAC) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + + mController.onBluetoothServiceConnected(mBluetoothA2dp); + + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAAC.getCodecId()))); + + verify(mCallback).onBluetoothCodecChanged(); + assertTrue(mPreference.isEnabled()); + } + + @Test + @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) + public void onPreferenceChange_listPreferenceIsNull() { + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(null); + assertFalse( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAAC.getCodecId()))); + } + + @Test + @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) + public void onPreferenceChange_unknownCodecId() { + assertFalse(mController.onPreferenceChange(mPreference, String.valueOf(TEST_ENTRY_VALUE))); + } + + @Test + @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) + public void onPreferenceChange_codecSelection() { + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) + .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); + mController.onBluetoothServiceConnected(mBluetoothA2dp); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAAC) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAAC.getCodecId()))); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigSBC) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeSBC.getCodecId()))); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigLDAC) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeLDAC.getCodecId()))); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAPTX) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAPTX.getCodecId()))); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigOPUS) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeOPUS.getCodecId()))); + } + + @Test + @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) + public void updateState_notifyPreference() { + assertFalse( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAAC.getCodecId()))); + + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAAC) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) + .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); mController.onBluetoothServiceConnected(mBluetoothA2dp); assertTrue( @@ -266,4 +364,96 @@ public class BluetoothCodecListPreferenceControllerTest { mController.onHDAudioEnabled(/* enabled= */ true); assertThat(mPreference.isEnabled()).isTrue(); } + + @Test + public void setupListPreference_wrongSize_shouldSetupDefaultListPreference() { + List entries = new ArrayList<>(1); + entries.add(TEST_ENTRY); + List entryValues = new ArrayList<>(2); + entryValues.add(TEST_ENTRY_VALUE); + entryValues.add(TEST_ENTRY_VALUE); + + mController.setupListPreference(entries, entryValues, "", ""); + verifySetupDefaultListPreference(); + } + + @Test + public void setupListPreference_listEmpty_shouldSetupDefaultListPreference() { + List entries = new ArrayList<>(1); + entries.add(TEST_ENTRY); + List entryValues = new ArrayList<>(); + + mController.setupListPreference(entries, entryValues, "", ""); + verifySetupDefaultListPreference(); + } + + @Test + public void getBluetoothCodecStatus_errorChecking() { + mController.onBluetoothServiceConnected(null); + assertThat(mController.getBluetoothCodecStatus()).isNull(); + + mController.onBluetoothServiceConnected(mBluetoothA2dp); + + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(null); + assertThat(mController.getBluetoothCodecStatus()).isNull(); + } + + @Test + public void getCurrentCodecConfig_errorChecking() { + mController.onBluetoothServiceConnected(null); + assertThat(mController.getCurrentCodecConfig()).isNull(); + + mController.onBluetoothServiceConnected(mBluetoothA2dp); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(null); + assertThat(mController.getCurrentCodecConfig()).isNull(); + } + + @Test + public void getCurrentCodecConfig_verifyConfig() { + mCodecStatus = new BluetoothCodecStatus.Builder().setCodecConfig(mCodecConfigAAC).build(); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + mController.onBluetoothServiceConnected(mBluetoothA2dp); + + assertThat(mController.getCurrentCodecConfig()).isEqualTo(mCodecConfigAAC); + } + + @Test + public void isHDAudioEnabled_errorChecking() { + mController.onBluetoothServiceConnected(null); + assertFalse(mController.isHDAudioEnabled()); + + mController.onBluetoothServiceConnected(mBluetoothA2dp); + when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) + .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); + assertFalse(mController.isHDAudioEnabled()); + } + + @Test + public void isHDAudioEnabled_verifyEnabled() { + mController.onBluetoothServiceConnected(mBluetoothA2dp); + when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)) + .thenReturn(BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); + assertTrue(mController.isHDAudioEnabled()); + } + + @Test + @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) + public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() { + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAAC) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); + mController.onBluetoothServiceConnected(mBluetoothA2dp); + + verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getExtendedCodecType()); + verify(mBluetoothA2dpConfigStore).setSampleRate(mCodecConfigAAC.getSampleRate()); + verify(mBluetoothA2dpConfigStore).setBitsPerSample(mCodecConfigAAC.getBitsPerSample()); + verify(mBluetoothA2dpConfigStore).setChannelMode(mCodecConfigAAC.getChannelMode()); + verify(mBluetoothA2dpConfigStore) + .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST); + verify(mBluetoothA2dpConfigStore) + .setCodecSpecific1Value(mCodecConfigAAC.getCodecSpecific1()); + } }