From 09e4fd3b62ebe4b18d5251387263bef013927c5e Mon Sep 17 00:00:00 2001 From: Dipankar Bhardwaj Date: Thu, 9 Jan 2025 06:56:38 -0800 Subject: [PATCH 01/12] Use RELEASE_OR_PREVIEW_DISPLAY to show android build version Change-Id: I6746ce0f501756775a3e2f769a36b572845c1ab7 Test: n/a Bug: 385863350 Flag: EXEMPT minor fix --- .../deviceinfo/storage/StorageItemPreferenceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index d4e2b7a3f19..c0caff7a494 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -459,7 +459,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle if (mSystemPreference != null) { mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate); mSystemPreference.setTitle(mContext.getString(R.string.storage_os_name, - Build.VERSION.RELEASE)); + Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY)); } if (mTemporaryFilesPreference != null) { mTemporaryFilesPreference.setStorageSize(storageCache.temporaryFilesSize, mTotalSize, From 6b7a5073f0c7c3fdee79ae5b13d379e578939de7 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 10 Jan 2025 09:46:24 +0000 Subject: [PATCH 02/12] developer settings: remove unused a2dp Preference Bug: 329809288 Flag: EXEMPT - unused code Test: m -j Change-Id: Ibd526fffddf5ea545afc437a5daee12bb1cf8746 --- ...ractBluetoothA2dpPreferenceController.java | 225 ------------------ ...BluetoothA2dpPreferenceControllerTest.java | 161 ------------- 2 files changed, 386 deletions(-) delete mode 100644 src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java diff --git a/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java b/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java deleted file mode 100644 index 09f3871cf78..00000000000 --- a/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2017 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.BluetoothA2dp; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothCodecConfig; -import android.bluetooth.BluetoothCodecStatus; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothManager; -import android.bluetooth.BluetoothProfile; -import android.content.Context; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnDestroy; -import com.android.settingslib.development.DeveloperOptionsPreferenceController; - -import java.util.List; - -public abstract class AbstractBluetoothA2dpPreferenceController extends - DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener, - PreferenceControllerMixin, BluetoothServiceConnectionListener, LifecycleObserver, - OnDestroy { - - @VisibleForTesting - static final int STREAMING_LABEL_ID = - com.android.settingslib.R.string.bluetooth_select_a2dp_codec_streaming_label; - - protected final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - protected BluetoothA2dp mBluetoothA2dp; - protected ListPreference mPreference; - private final String[] mListValues; - private final String[] mListSummaries; - - @VisibleForTesting - BluetoothAdapter mBluetoothAdapter; - - public AbstractBluetoothA2dpPreferenceController(Context context, Lifecycle lifecycle, - BluetoothA2dpConfigStore store) { - super(context); - - mBluetoothA2dpConfigStore = store; - mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); - mListValues = getListValues(); - mListSummaries = getListSummaries(); - - if (lifecycle != null) { - lifecycle.addObserver(this); - } - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - - mPreference = screen.findPreference(getPreferenceKey()); - - // Set a default value because BluetoothCodecConfig is null initially. - mPreference.setValue(mListValues[getDefaultIndex()]); - mPreference.setSummary(mListSummaries[getDefaultIndex()]); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (mBluetoothA2dp == null) { - return false; - } - - writeConfigurationValues(newValue); - - final BluetoothCodecConfig codecConfig = mBluetoothA2dpConfigStore.createCodecConfig(); - synchronized (mBluetoothA2dpConfigStore) { - BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null) { - return false; - } - setCodecConfigPreference(activeDevice, codecConfig); - } - // Because the setting is not persisted into permanent storage, we cannot call update state - // here to update the preference. - // Instead, we just assume it was set and update the preference here. - final int index = mPreference.findIndexOfValue(newValue.toString()); - // We only want to append "Streaming" if not using default - if (index == getDefaultIndex()) { - mPreference.setSummary(mListSummaries[index]); - } else { - mPreference.setSummary( - mContext.getResources().getString(STREAMING_LABEL_ID, mListSummaries[index])); - } - return true; - } - - @Override - public void updateState(Preference preference) { - BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null || getCodecConfig(activeDevice) == null || mPreference == null) { - return; - } - - BluetoothCodecConfig codecConfig; - synchronized (mBluetoothA2dpConfigStore) { - codecConfig = getCodecConfig(activeDevice); - } - - final int index = getCurrentA2dpSettingIndex(codecConfig); - mPreference.setValue(mListValues[index]); - - // We only want to append "Streaming" if not using default - if (index == getDefaultIndex()) { - mPreference.setSummary(mListSummaries[index]); - } else { - mPreference.setSummary( - mContext.getResources().getString(STREAMING_LABEL_ID, mListSummaries[index])); - } - - writeConfigurationValues(mListValues[index]); - } - - @Override - public void onBluetoothServiceConnected(BluetoothA2dp bluetoothA2dp) { - mBluetoothA2dp = bluetoothA2dp; - updateState(mPreference); - } - - @Override - public void onBluetoothCodecUpdated() { - // intentional no-op - // We do not want to call update state here because the setting is not persisted in - // permanent storage. - } - - @Override - public void onBluetoothServiceDisconnected() { - mBluetoothA2dp = null; - } - - @Override - public void onDestroy() { - mBluetoothA2dp = null; - } - - /** - * @return an array of string values that correspond to the current {@link ListPreference}. - */ - protected abstract String[] getListValues(); - - /** - * @return an array of string summaries that correspond to the current {@link ListPreference}. - */ - protected abstract String[] getListSummaries(); - - /** - * Updates the new value to the {@link BluetoothA2dpConfigStore} and the {@link BluetoothA2dp}. - * - * @param newValue the new setting value - */ - protected abstract void writeConfigurationValues(Object newValue); - - /** - * @return the current selected index for the {@link ListPreference}. - */ - protected abstract int getCurrentA2dpSettingIndex(BluetoothCodecConfig config); - - /** - * @return default setting index for the {@link ListPreference}. - */ - protected abstract int getDefaultIndex(); - - @VisibleForTesting - void setCodecConfigPreference(BluetoothDevice device, - BluetoothCodecConfig config) { - BluetoothDevice bluetoothDevice = - (device != null) ? device : getA2dpActiveDevice(); - if (bluetoothDevice == null) { - return; - } - mBluetoothA2dp.setCodecConfigPreference(bluetoothDevice, config); - } - - @VisibleForTesting - BluetoothCodecConfig getCodecConfig(BluetoothDevice device) { - if (mBluetoothA2dp != null) { - BluetoothDevice bluetoothDevice = - (device != null) ? device : getA2dpActiveDevice(); - if (bluetoothDevice == null) { - return null; - } - BluetoothCodecStatus codecStatus = mBluetoothA2dp.getCodecStatus(bluetoothDevice); - if (codecStatus != null) { - return codecStatus.getCodecConfig(); - } - } - return null; - } - - private BluetoothDevice getA2dpActiveDevice() { - if (mBluetoothAdapter == null) { - return null; - } - List activeDevices = - mBluetoothAdapter.getActiveDevices(BluetoothProfile.A2DP); - return (activeDevices.size() > 0) ? activeDevices.get(0) : null; - } -} diff --git a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java deleted file mode 100644 index 783c2edb0f9..00000000000 --- a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2017 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 com.android.settings.development.AbstractBluetoothA2dpPreferenceController - .STREAMING_LABEL_ID; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -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.BluetoothCodecConfig; -import android.content.Context; - -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.ListPreference; -import androidx.preference.PreferenceScreen; - -import com.android.settingslib.core.lifecycle.Lifecycle; - -import org.junit.Before; -import org.junit.Ignore; -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 AbstractBluetoothA2dpPreferenceControllerTest { - - @Mock - private BluetoothA2dp mBluetoothA2dp; - @Mock - private BluetoothCodecConfig mBluetoothCodecConfig; - @Mock - private ListPreference mPreference; - @Mock - private PreferenceScreen mScreen; - @Mock - private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; - private Context mContext; - private AbstractBluetoothA2dpPreferenceController mController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); - mController = spy(new AbstractBluetoothA2dpPreferenceControllerImpl(mContext, mLifecycle, - mBluetoothA2dpConfigStore)); - mController.mBluetoothAdapter = null; - doReturn(mBluetoothCodecConfig).when(mController).getCodecConfig(null); - doNothing().when(mController).setCodecConfigPreference(any(), any()); - when(mBluetoothA2dpConfigStore.createCodecConfig()).thenReturn(mBluetoothCodecConfig); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - mController.displayPreference(mScreen); - } - - @Test - @Ignore - public void onPreferenceChange_bluetoothConnected_shouldUpdateCodec() { - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.onPreferenceChange(mPreference, "" /* new value */); - - verify(mController).setCodecConfigPreference(any(), any()); - } - - @Test - public void onPreferenceChange_bluetoothNotConnected_shouldNotUpdateCodec() { - mController.onBluetoothServiceDisconnected(); - - mController.onPreferenceChange(mPreference, "" /* new value */); - - verify(mController, never()).setCodecConfigPreference(any(), any()); - } - - @Test - @Ignore - public void updateState_option2Set_shouldUpdateToOption2() { - when(mBluetoothCodecConfig.getSampleRate()).thenReturn( - BluetoothCodecConfig.SAMPLE_RATE_48000); - - doReturn(2).when(mController).getCurrentA2dpSettingIndex(any()); - mController.updateState(mPreference); - - verify(mPreference).setValue(mController.getListValues()[2]); - verify(mPreference).setSummary(mContext.getString(STREAMING_LABEL_ID, - mController.getListSummaries()[2])); - } - - @Test - public void onBluetoothServiceConnected_shouldUpdateState() { - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - verify(mController).updateState(mPreference); - } - - private static class AbstractBluetoothA2dpPreferenceControllerImpl - extends AbstractBluetoothA2dpPreferenceController { - - private AbstractBluetoothA2dpPreferenceControllerImpl(Context context, - Lifecycle lifecycle, BluetoothA2dpConfigStore store) { - super(context, lifecycle, store); - } - - @Override - public String getPreferenceKey() { - return null; - } - - @Override - protected String[] getListValues() { - return new String[]{"1", "2", "3"}; - } - - @Override - protected String[] getListSummaries() { - return new String[]{"foo", "bar", "foobar"}; - } - - @Override - protected void writeConfigurationValues(Object newValue) { - } - - @Override - protected int getCurrentA2dpSettingIndex(BluetoothCodecConfig config) { - return 0; - } - - @Override - protected int getDefaultIndex() { - return 0; - } - } -} From 9e890a93f897644edf6017e1dc1d763aa1752b03 Mon Sep 17 00:00:00 2001 From: Riley Jones Date: Tue, 14 Jan 2025 01:27:45 +0000 Subject: [PATCH 03/12] Cleanup qs shortcut flag in OneHandedSettingsUtils Test: atest OneHandedSettingsUtilsTest Bug: 367414968 Flag: EXEMPT flag cleanup Change-Id: Ic906bd025ea9df7c5b083899608be4e1324ae317 --- .../gestures/OneHandedSettingsUtils.java | 14 ++++---------- .../gestures/OneHandedSettingsUtilsTest.java | 17 ----------------- 2 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java index fe7db4f7c3e..cba40bd0302 100644 --- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java +++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java @@ -257,16 +257,10 @@ public class OneHandedSettingsUtils { return true; } - if (android.view.accessibility.Flags.a11yQsShortcut()) { - // Checks QS_SHORTCUT_KEY - final String targetsQs = Settings.Secure.getStringForUser(context.getContentResolver(), - Settings.Secure.ACCESSIBILITY_QS_TARGETS, sCurrentUserId); - if (!TextUtils.isEmpty(targetsQs) && targetsQs.contains(ONE_HANDED_MODE_TARGET_NAME)) { - return true; - } - } - - return false; + // Checks QS_SHORTCUT_KEY + final String targetsQs = Settings.Secure.getStringForUser(context.getContentResolver(), + Settings.Secure.ACCESSIBILITY_QS_TARGETS, sCurrentUserId); + return !TextUtils.isEmpty(targetsQs) && targetsQs.contains(ONE_HANDED_MODE_TARGET_NAME); } /** diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java index ee5f72ed2d4..ab1682a192f 100644 --- a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java +++ b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsUtilsTest.java @@ -22,14 +22,9 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.UserHandle; -import android.platform.test.annotations.DisableFlags; -import android.platform.test.annotations.EnableFlags; -import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; -import android.view.accessibility.Flags; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -37,8 +32,6 @@ import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class OneHandedSettingsUtilsTest { - @Rule - public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final int OFF = 0; private static final int ON = 1; @@ -162,7 +155,6 @@ public class OneHandedSettingsUtilsTest { } @Test - @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) public void getShortcutEnabled_qsShortcutEnabled_returnTrue() { setupShortcuts( /* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true); @@ -170,15 +162,6 @@ public class OneHandedSettingsUtilsTest { assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isTrue(); } - @Test - @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) - public void getShortcutEnabled_flagDisabled_qsShortcutEnabled_returnFalse() { - setupShortcuts( - /* enableFab= */ false, /* enableVolumeKeys= */ false, /* enableQs=*/ true); - - assertThat(OneHandedSettingsUtils.getShortcutEnabled(mContext)).isFalse(); - } - private void setupShortcuts(boolean enableFab, boolean enableVolumeKeys, boolean enableQs) { setupShortcut(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, enableFab); setupShortcut(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, enableVolumeKeys); From 37749d5ee270d3eb7be760848ceaf8f1c52ea3de Mon Sep 17 00:00:00 2001 From: danielwbhuang Date: Tue, 14 Jan 2025 22:04:34 +0800 Subject: [PATCH 04/12] Add metrics to the regional preferences implementation 1. Region 2. Temperature 3. Measurement system 4. First day of week Bug: 389568296 Flag: EXEMPT metrics Test: manual Change-Id: I62c1cbcec873b33c76fd389c27e7809c7581db97 --- .../FirstDayOfWeekItemFragment.java | 18 ++++++++++++++++++ .../MeasurementSystemItemFragment.java | 19 +++++++++++++++++++ .../RegionDialogFragment.java | 16 +++++++++++++++- .../RegionPickerFragment.java | 19 ++++++++++++++++++- .../TemperatureUnitFragment.java | 18 ++++++++++++++++++ 5 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/regionalpreferences/FirstDayOfWeekItemFragment.java b/src/com/android/settings/regionalpreferences/FirstDayOfWeekItemFragment.java index 72a841e06d2..a90edf4a8fb 100644 --- a/src/com/android/settings/regionalpreferences/FirstDayOfWeekItemFragment.java +++ b/src/com/android/settings/regionalpreferences/FirstDayOfWeekItemFragment.java @@ -18,11 +18,16 @@ package com.android.settings.regionalpreferences; import android.app.settings.SettingsEnums; import android.content.Context; +import android.provider.Settings; + +import androidx.annotation.NonNull; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; @@ -36,6 +41,19 @@ public class FirstDayOfWeekItemFragment extends DashboardFragment { private static final String KEY_PREFERENCE_CATEGORY_FIRST_DAY_OF_WEEK_ITEM = "first_day_of_week_item_category"; + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + MetricsFeatureProvider metricsFeatureProvider = + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); + String action = getIntent() != null ? getIntent().getAction() : ""; + if (Settings.ACTION_FIRST_DAY_OF_WEEK_SETTINGS.equals(action)) { + metricsFeatureProvider.action( + context, SettingsEnums.ACTION_OPEN_FIRST_DAY_OF_WEEK_OUTSIDE_SETTINGS); + } + } + @Override protected int getPreferenceScreenResId() { return R.xml.regional_preferences_first_day_of_week; diff --git a/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java b/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java index 231a34e6afd..1d4a1d43e90 100644 --- a/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java +++ b/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java @@ -18,12 +18,17 @@ package com.android.settings.regionalpreferences; import android.app.settings.SettingsEnums; import android.content.Context; +import android.provider.Settings; + +import androidx.annotation.NonNull; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; @@ -36,6 +41,20 @@ public class MeasurementSystemItemFragment extends DashboardFragment { private static final String LOG_TAG = "MeasurementSystemItemFragment"; private static final String KEY_PREFERENCE_CATEGORY_MEASUREMENT_SYSTEM_ITEM = "measurement_system_item_category"; + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + MetricsFeatureProvider metricsFeatureProvider = + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); + String action = getIntent() != null ? getIntent().getAction() : ""; + if (Settings.ACTION_MEASUREMENT_SYSTEM_SETTINGS.equals(action)) { + metricsFeatureProvider.action( + context, SettingsEnums.ACTION_OPEN_MEASUREMENT_SYSTEM_OUTSIDE_SETTINGS); + } + } + @Override protected int getPreferenceScreenResId() { return R.xml.regional_preferences_measurement_system; diff --git a/src/com/android/settings/regionalpreferences/RegionDialogFragment.java b/src/com/android/settings/regionalpreferences/RegionDialogFragment.java index 3f6aa54ce66..7bfc82801e6 100644 --- a/src/com/android/settings/regionalpreferences/RegionDialogFragment.java +++ b/src/com/android/settings/regionalpreferences/RegionDialogFragment.java @@ -17,6 +17,7 @@ package com.android.settings.regionalpreferences; import android.app.Dialog; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; @@ -35,6 +36,8 @@ import com.android.internal.app.LocalePicker; import com.android.internal.app.LocaleStore; import com.android.settings.R; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.Locale; import java.util.Set; @@ -61,7 +64,7 @@ public class RegionDialogFragment extends InstrumentedDialogFragment { @Override public int getMetricsCategory() { - return 0; + return SettingsEnums.CHANGE_REGION_DIALOG; } @NonNull @@ -110,6 +113,7 @@ public class RegionDialogFragment extends InstrumentedDialogFragment { private final Context mContext; private final int mDialogType; private final LocaleStore.LocaleInfo mLocaleInfo; + private final MetricsFeatureProvider mMetricsFeatureProvider; RegionDialogController( @NonNull Context context, @NonNull RegionDialogFragment dialogFragment) { @@ -117,6 +121,8 @@ public class RegionDialogFragment extends InstrumentedDialogFragment { Bundle arguments = dialogFragment.getArguments(); mDialogType = arguments.getInt(ARG_DIALOG_TYPE); mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(ARG_TARGET_LOCALE); + mMetricsFeatureProvider = + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @Override @@ -124,6 +130,14 @@ public class RegionDialogFragment extends InstrumentedDialogFragment { if (mDialogType == DIALOG_CHANGE_LOCALE_REGION) { if (which == DialogInterface.BUTTON_POSITIVE) { updateRegion(mLocaleInfo.getLocale().toLanguageTag()); + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_CHANGE_REGION_DIALOG_POSITIVE_BTN_CLICKED); + } + if (which == DialogInterface.BUTTON_NEGATIVE) { + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_CHANGE_REGION_DIALOG_NEGATIVE_BTN_CLICKED); } dismiss(); if (getActivity() != null) { diff --git a/src/com/android/settings/regionalpreferences/RegionPickerFragment.java b/src/com/android/settings/regionalpreferences/RegionPickerFragment.java index b1759f18b84..cf4d9b99ba0 100644 --- a/src/com/android/settings/regionalpreferences/RegionPickerFragment.java +++ b/src/com/android/settings/regionalpreferences/RegionPickerFragment.java @@ -16,8 +16,10 @@ package com.android.settings.regionalpreferences; +import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Bundle; +import android.provider.Settings; import androidx.annotation.NonNull; @@ -25,8 +27,10 @@ import com.android.internal.app.LocaleStore; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.flags.Flags; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.ArrayList; import java.util.List; @@ -44,6 +48,19 @@ public class RegionPickerFragment extends DashboardFragment{ super.onCreate(icicle); } + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + MetricsFeatureProvider metricsFeatureProvider = + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); + String action = getIntent() != null ? getIntent().getAction() : ""; + if (Settings.ACTION_REGION_SETTINGS.equals(action)) { + metricsFeatureProvider.action( + context, SettingsEnums.ACTION_OPEN_REGION_OUTSIDE_SETTINGS); + } + } + @Override protected int getPreferenceScreenResId() { return R.xml.system_region_picker; @@ -56,7 +73,7 @@ public class RegionPickerFragment extends DashboardFragment{ @Override public int getMetricsCategory() { - return 0; + return SettingsEnums.REGION_SETTINGS; } @Override diff --git a/src/com/android/settings/regionalpreferences/TemperatureUnitFragment.java b/src/com/android/settings/regionalpreferences/TemperatureUnitFragment.java index 7c9b6af81d7..c10323fbd30 100644 --- a/src/com/android/settings/regionalpreferences/TemperatureUnitFragment.java +++ b/src/com/android/settings/regionalpreferences/TemperatureUnitFragment.java @@ -18,11 +18,16 @@ package com.android.settings.regionalpreferences; import android.app.settings.SettingsEnums; import android.content.Context; +import android.provider.Settings; + +import androidx.annotation.NonNull; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; @@ -36,6 +41,19 @@ public class TemperatureUnitFragment extends DashboardFragment { private static final String KEY_PREFERENCE_CATEGORY_TEMPERATURE_UNIT = "temperature_unit_category"; + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + MetricsFeatureProvider metricsFeatureProvider = + FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); + String action = getIntent() != null ? getIntent().getAction() : ""; + if (Settings.ACTION_TEMPERATURE_UNIT_SETTINGS.equals(action)) { + metricsFeatureProvider.action( + context, SettingsEnums.ACTION_OPEN_TEMPERATURE_UNIT_OUTSIDE_SETTINGS); + } + } + @Override protected int getPreferenceScreenResId() { return R.xml.regional_preferences_temperature; From 0dc355930f80c0957a34fb8305dc56af1796a731 Mon Sep 17 00:00:00 2001 From: Mill Chen Date: Wed, 15 Jan 2025 05:45:59 +0000 Subject: [PATCH 05/12] Update background color for Settings homepage Fix: 317163103 Test: visual verify Flag: EXEMPT bug fix Change-Id: I121dc44181c9c3d6cd1b46ee444371050337186b --- res/values/themes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/themes.xml b/res/values/themes.xml index 9d416f729fd..0a1809755c0 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -202,7 +202,7 @@ @android:color/white ?attr/colorPrimaryDark - @android:color/system_surface_container_light + @color/settingslib_materialColorSurfaceContainerLow + + From d0d793da2e514e431099e8a2c36ea9883e0e8253 Mon Sep 17 00:00:00 2001 From: Fan Wu Date: Tue, 14 Jan 2025 15:01:59 +0800 Subject: [PATCH 07/12] [Catalyst] Remove BooleanValue usages Bug: 388167302 Test: atest and manual Flag: EXEMPT refactor NO_IFTTT=refactor Change-Id: Ia3d14143185708e34325a641cb872d7e2675e3bc --- src/com/android/settings/display/AutoBrightnessScreen.kt | 6 ++---- src/com/android/settings/display/darkmode/DarkModeScreen.kt | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/display/AutoBrightnessScreen.kt b/src/com/android/settings/display/AutoBrightnessScreen.kt index ed9e078ffb6..48ef210e360 100644 --- a/src/com/android/settings/display/AutoBrightnessScreen.kt +++ b/src/com/android/settings/display/AutoBrightnessScreen.kt @@ -29,8 +29,7 @@ import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.SettingsStore import com.android.settingslib.datastore.SettingsSystemStore -import com.android.settingslib.metadata.BooleanValue -import com.android.settingslib.metadata.PersistentPreference +import com.android.settingslib.metadata.BooleanPreference import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.ProvidePreferenceScreen @@ -46,8 +45,7 @@ class AutoBrightnessScreen : PreferenceScreenBinding, PreferenceAvailabilityProvider, PreferenceRestrictionMixin, - PersistentPreference, - BooleanValue { + BooleanPreference { override val key: String get() = KEY diff --git a/src/com/android/settings/display/darkmode/DarkModeScreen.kt b/src/com/android/settings/display/darkmode/DarkModeScreen.kt index 963a641c4d3..f1a95f59874 100644 --- a/src/com/android/settings/display/darkmode/DarkModeScreen.kt +++ b/src/com/android/settings/display/darkmode/DarkModeScreen.kt @@ -25,8 +25,7 @@ import com.android.settings.flags.Flags import com.android.settingslib.PrimarySwitchPreference import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.datastore.Permissions -import com.android.settingslib.metadata.BooleanValue -import com.android.settingslib.metadata.PersistentPreference +import com.android.settingslib.metadata.BooleanPreference import com.android.settingslib.metadata.PreferenceMetadata import com.android.settingslib.metadata.PreferenceSummaryProvider import com.android.settingslib.metadata.ProvidePreferenceScreen @@ -41,8 +40,7 @@ import com.android.settingslib.preference.PreferenceScreenCreator class DarkModeScreen(context: Context) : PreferenceScreenCreator, PreferenceScreenBinding, - PersistentPreference, - BooleanValue, + BooleanPreference, PreferenceSummaryProvider { private val darkModeStorage = DarkModeStorage(context) From 2c869d337c95d682e36be816dd7bc2b01bbcbf2f Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 10 Jan 2025 08:06:55 +0000 Subject: [PATCH 08/12] 24Q4: Removal of a2dp_offload_codec_extensibility_settings Bug: 323319530 Fix: 323319530 Flag: EXEMPT removing com.android.settings.development.a2dp_offload_codec_extensibility_settings Test: atest SettingsRoboTests Change-Id: If9c710c0aaed7326b32dd2e7d5f3109de4047b97 --- .../settings_core_flag_declarations.aconfig | 7 - res/layout/bluetooth_audio_codec_dialog.xml | 75 ----- res/xml/development_settings.xml | 8 - .../development/BluetoothA2dpConfigStore.java | 28 +- .../DevelopmentSettingsDashboardFragment.java | 6 +- ...ctBluetoothDialogPreferenceController.java | 2 +- .../BluetoothCodecDialogPreference.java | 77 ----- ...etoothCodecDialogPreferenceController.java | 207 ------------- ...luetoothCodecListPreferenceController.java | 14 +- ...uetoothDialogPreferenceControllerTest.java | 2 +- ...thCodecDialogPreferenceControllerTest.java | 279 ------------------ .../BluetoothCodecDialogPreferenceTest.java | 50 ---- ...oothCodecListPreferenceControllerTest.java | 26 +- 13 files changed, 23 insertions(+), 758 deletions(-) delete mode 100644 res/layout/bluetooth_audio_codec_dialog.xml delete mode 100644 src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreference.java delete mode 100644 src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java diff --git a/aconfig/development/settings_core_flag_declarations.aconfig b/aconfig/development/settings_core_flag_declarations.aconfig index fec67f6b782..b73b0268009 100644 --- a/aconfig/development/settings_core_flag_declarations.aconfig +++ b/aconfig/development/settings_core_flag_declarations.aconfig @@ -1,13 +1,6 @@ package: "com.android.settings.development" container: "system" -flag { - name: "a2dp_offload_codec_extensibility_settings" - namespace: "bluetooth" - description: "Feature flag for Bluetooth Audio Codec extensibility in Settings" - bug: "323319530" -} - flag { name: "deprecate_list_activity" namespace: "android_settings" diff --git a/res/layout/bluetooth_audio_codec_dialog.xml b/res/layout/bluetooth_audio_codec_dialog.xml deleted file mode 100644 index 3a260a655e7..00000000000 --- a/res/layout/bluetooth_audio_codec_dialog.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 28492380f32..6ac175d85bd 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -434,14 +434,6 @@ android:key="bluetooth_hd_audio_settings" android:title="@string/bluetooth_profile_a2dp_high_quality_unknown_codec"/> - - getSelectableIndex() { - List index = new ArrayList<>(); - final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; - - index.add(getDefaultIndex()); - if (bluetoothA2dp == null) { - return index; - } - final BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null) { - Log.d(TAG, "Unable to get selectable index. No Active Bluetooth device"); - return index; - } - // Check HD audio is enabled, display the available list. - if (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice) - == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { - List configs = getSelectableConfigs(activeDevice); - if (configs != null) { - return getIndexFromConfig(configs); - } - } - // If HD audio is disabled, SBC is the only one available codec. - index.add(convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)); - return index; - } - - @Override - protected void writeConfigurationValues(final int index) { - int codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; // default - int codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; - switch (index) { - case 0: - final BluetoothDevice activeDevice = getA2dpActiveDevice(); - codecTypeValue = getHighestCodec(mBluetoothA2dp, activeDevice, - getSelectableConfigs(activeDevice)); - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 1: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 2: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 3: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 4: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 5: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 6: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 7: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - default: - break; - } - mBluetoothA2dpConfigStore.setCodecType(codecTypeValue); - mBluetoothA2dpConfigStore.setCodecPriority(codecPriorityValue); - - // Once user changes codec, to reset configs with highest quality. - final BluetoothCodecConfig config = getSelectableByCodecType(codecTypeValue); - if (config == null) { - Log.d(TAG, "Selectable config is null. Unable to reset"); - } - mBluetoothA2dpConfigStore.setSampleRate(getHighestSampleRate(config)); - mBluetoothA2dpConfigStore.setBitsPerSample(getHighestBitsPerSample(config)); - mBluetoothA2dpConfigStore.setChannelMode(getHighestChannelMode(config)); - } - - @Override - protected int getCurrentIndexByConfig(BluetoothCodecConfig config) { - if (config == null) { - Log.e(TAG, "Unable to get current config index. Config is null."); - } - return convertCfgToBtnIndex(config.getCodecType()); - } - - @Override - public void onIndexUpdated(int index) { - super.onIndexUpdated(index); - mCallback.onBluetoothCodecChanged(); - } - - @Override - public void onHDAudioEnabled(boolean enabled) { - writeConfigurationValues(/* index= */ 0); - } - - private List getIndexFromConfig(List configs) { - List indexArray = new ArrayList<>(); - for (BluetoothCodecConfig config : configs) { - indexArray.add(convertCfgToBtnIndex(config.getCodecType())); - } - return indexArray; - } - - @VisibleForTesting - int convertCfgToBtnIndex(int config) { - int index = getDefaultIndex(); - switch (config) { - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC: - index = 1; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC: - index = 2; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX: - index = 3; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD: - index = 4; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC: - index = 5; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: - index = 7; - break; - default: - Log.e(TAG, "Unsupported config:" + config); - break; - } - return index; - } -} diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java index 72da5053a69..11ed93cbd46 100644 --- a/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java +++ b/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java @@ -32,7 +32,6 @@ 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; import java.util.ArrayList; @@ -62,9 +61,7 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre @Override public boolean isAvailable() { - boolean available = Flags.a2dpOffloadCodecExtensibilitySettings(); - Log.d(TAG, "isAvailable: " + available); - return available; + return true; } @Override @@ -80,10 +77,6 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre @Override public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) { - if (!Flags.a2dpOffloadCodecExtensibilitySettings()) { - return false; - } - if (mListPreference == null) { Log.e(TAG, "onPreferenceChange: List preference is null"); return false; @@ -115,7 +108,7 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre } BluetoothCodecConfig codecConfig = - mBluetoothA2dpConfigStore.createCodecConfigFromCodecType(); + mBluetoothA2dpConfigStore.createCodecConfig(); Log.d(TAG, "onPreferenceChange: setCodecConfigPreference: " + codecConfig.toString()); bluetoothA2dp.setCodecConfigPreference(activeDevice, codecConfig); if (mCallback != null) { @@ -128,9 +121,6 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre @Override public void updateState(@Nullable Preference preference) { super.updateState(preference); - if (!Flags.a2dpOffloadCodecExtensibilitySettings()) { - return; - } if (!isHDAudioEnabled()) { Log.d(TAG, "updateState: HD Audio is disabled"); diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java index 42b889cfa1a..9825c994374 100644 --- a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java @@ -220,7 +220,7 @@ public class AbstractBluetoothDialogPreferenceControllerTest { mActiveDevice)).thenReturn(mCodecStatus); mController.onBluetoothServiceConnected(mBluetoothA2dp); - verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getCodecType()); + verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getExtendedCodecType()); verify(mBluetoothA2dpConfigStore).setSampleRate(mCodecConfigAAC.getSampleRate()); verify(mBluetoothA2dpConfigStore).setBitsPerSample(mCodecConfigAAC.getBitsPerSample()); verify(mBluetoothA2dpConfigStore).setChannelMode(mCodecConfigAAC.getChannelMode()); diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java deleted file mode 100644 index de2b363ed9b..00000000000 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2019 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 com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.atLeastOnce; -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.PreferenceScreen; - -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.Arrays; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class BluetoothCodecDialogPreferenceControllerTest { - - private static final String DEVICE_ADDRESS = "00:11:22:33:44:55"; - - @Mock - private BluetoothA2dp mBluetoothA2dp; - @Mock - private BluetoothAdapter mBluetoothAdapter; - @Mock - private PreferenceScreen mScreen; - @Mock - private AbstractBluetoothPreferenceController.Callback mCallback; - - private BluetoothCodecDialogPreferenceController mController; - private BluetoothCodecDialogPreference mPreference; - private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - private BluetoothCodecStatus mCodecStatus; - private BluetoothCodecConfig mCodecConfigAAC; - private BluetoothCodecConfig mCodecConfigSBC; - private BluetoothCodecConfig mCodecConfigAPTX; - private BluetoothCodecConfig mCodecConfigAPTXHD; - private BluetoothCodecConfig mCodecConfigLDAC; - private BluetoothCodecConfig mCodecConfigOPUS; - 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 = new BluetoothCodecDialogPreferenceController(mContext, mLifecycle, - mBluetoothA2dpConfigStore, mCallback); - mController.mBluetoothAdapter = mBluetoothAdapter; - mPreference = new BluetoothCodecDialogPreference(mContext); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - mController.displayPreference(mScreen); - mCodecConfigSBC = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_96000 - | BluetoothCodecConfig.SAMPLE_RATE_176400) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_32) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_MONO - | BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .build(); - mCodecConfigAAC = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000 - | BluetoothCodecConfig.SAMPLE_RATE_88200) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16 - | BluetoothCodecConfig.BITS_PER_SAMPLE_24) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .build(); - mCodecConfigAPTX = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) - .build(); - mCodecConfigAPTXHD = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) - .build(); - mCodecConfigLDAC = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) - .build(); - mCodecConfigOPUS = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) - .build(); - when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.A2DP))) - .thenReturn(Arrays.asList(mActiveDevice)); - } - - @Test - public void writeConfigurationValues_selectDefault_setHighest() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC, - mCodecConfigSBC}; - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigSBC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( - BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.writeConfigurationValues(0); - verify(mBluetoothA2dpConfigStore).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS); - } - - @Test - public void writeConfigurationValues_checkCodec() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC, - mCodecConfigSBC, mCodecConfigAPTX, mCodecConfigAPTXHD, mCodecConfigLDAC}; - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigSBC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.writeConfigurationValues(1); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC); - - mController.writeConfigurationValues(2); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC); - - mController.writeConfigurationValues(3); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX); - - mController.writeConfigurationValues(4); - verify(mBluetoothA2dpConfigStore).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD); - - mController.writeConfigurationValues(5); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC); - - mController.writeConfigurationValues(7); - verify(mBluetoothA2dpConfigStore).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS); - } - - @Test - public void writeConfigurationValues_resetHighestConfig() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX, - mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigOPUS}; - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigAAC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - mController.writeConfigurationValues(2); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecPriority( - BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setSampleRate( - BluetoothCodecConfig.SAMPLE_RATE_88200); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setBitsPerSample( - BluetoothCodecConfig.BITS_PER_SAMPLE_24); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setChannelMode( - BluetoothCodecConfig.CHANNEL_MODE_STEREO); - } - - @Test - public void getCurrentIndexByConfig_verifyIndex() { - assertThat(mController.getCurrentIndexByConfig(mCodecConfigAAC)).isEqualTo( - mController.convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)); - } - - @Test - public void getCurrentIndexByConfig_verifyOpusIndex() { - assertThat(mController.getCurrentIndexByConfig(mCodecConfigOPUS)).isEqualTo( - mController.convertCfgToBtnIndex( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)); - } - - - @Test - public void onIndexUpdated_notifyPreference() { - mController.onIndexUpdated(0); - - verify(mCallback).onBluetoothCodecChanged(); - } - - @Test - public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsOpus() { - List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, - mCodecConfigAAC, mCodecConfigSBC); - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigOPUS) - .setCodecsSelectableCapabilities(mCodecConfigs) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( - BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.onHDAudioEnabled(/* enabled= */ true); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)); - } - - @Test - public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsAAC() { - List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, - mCodecConfigAAC, mCodecConfigSBC); - 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); - - mController.onHDAudioEnabled(/* enabled= */ true); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)); - } - @Test - public void onHDAudioEnabled_optionalCodecDisabled_setsCodecTypeAsSBC() { - List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, - mCodecConfigAAC, mCodecConfigSBC); - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigAAC) - .setCodecsSelectableCapabilities(mCodecConfigs) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( - BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.onHDAudioEnabled(/* enabled= */ false); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)); - } -} diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java deleted file mode 100644 index 4b8df164fe6..00000000000 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2019 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 com.google.common.truth.Truth.assertThat; - -import android.content.Context; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class BluetoothCodecDialogPreferenceTest { - - private BluetoothCodecDialogPreference mPreference; - private Context mContext; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mPreference = new BluetoothCodecDialogPreference(mContext); - } - - @Test - public void getRadioButtonGroupId() { - assertThat(mPreference.getRadioButtonGroupId()) - .isEqualTo(R.id.bluetooth_audio_codec_radio_group); - } -} 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 4ac5dff1eef..a99dc2b1f55 100644 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java @@ -18,7 +18,6 @@ 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; @@ -35,14 +34,12 @@ import android.bluetooth.BluetoothCodecType; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; -import android.platform.test.annotations.EnableFlags; import androidx.lifecycle.LifecycleOwner; import androidx.preference.ListPreference; import androidx.preference.PreferenceScreen; import com.android.settings.development.BluetoothA2dpConfigStore; -import com.android.settings.development.Flags; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; @@ -73,6 +70,7 @@ public class BluetoothCodecListPreferenceControllerTest { private BluetoothCodecType mCodecTypeAAC; private BluetoothCodecType mCodecTypeSBC; private BluetoothCodecType mCodecTypeAPTX; + private BluetoothCodecType mCodecTypeAPTXHD; private BluetoothCodecType mCodecTypeLDAC; private BluetoothCodecType mCodecTypeOPUS; private List mCodecTypes; @@ -114,6 +112,8 @@ public class BluetoothCodecListPreferenceControllerTest { BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC); mCodecTypeAPTX = BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX); + mCodecTypeAPTXHD = + BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD); mCodecTypeLDAC = BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC); mCodecTypeOPUS = @@ -125,6 +125,7 @@ public class BluetoothCodecListPreferenceControllerTest { mCodecTypeSBC, mCodecTypeAAC, mCodecTypeAPTX, + mCodecTypeAPTXHD, mCodecTypeLDAC, mCodecTypeOPUS)); @@ -212,6 +213,11 @@ public class BluetoothCodecListPreferenceControllerTest { mController.writeConfigurationValues(String.valueOf(mCodecTypeAPTX.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTX); + assertTrue( + mController.writeConfigurationValues(String.valueOf( + mCodecTypeAPTXHD.getCodecId()))); + verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTXHD); + assertTrue( mController.writeConfigurationValues(String.valueOf(mCodecTypeLDAC.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeLDAC); @@ -244,7 +250,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onPreferenceChange_notifyPreference() { assertFalse( mController.onPreferenceChange( @@ -271,7 +276,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onPreferenceChange_listPreferenceIsNull() { when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(null); assertFalse( @@ -280,13 +284,11 @@ public class BluetoothCodecListPreferenceControllerTest { } @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)) @@ -325,6 +327,14 @@ public class BluetoothCodecListPreferenceControllerTest { assertTrue( mController.onPreferenceChange( mPreference, String.valueOf(mCodecTypeAPTX.getCodecId()))); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAPTXHD) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAPTXHD.getCodecId()))); mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigOPUS) @@ -336,7 +346,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void updateState_notifyPreference() { assertFalse( mController.onPreferenceChange( @@ -437,7 +446,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() { mCodecStatus = new BluetoothCodecStatus.Builder() From 672fcd51ab1b9d039d75dd0a4f60e6e7c249c7c0 Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 10 Jan 2025 09:46:24 +0000 Subject: [PATCH 09/12] developer settings: remove unused a2dp Preference Bug: 329809288 Flag: EXEMPT - unused code Test: m -j Merged-In: Ibd526fffddf5ea545afc437a5daee12bb1cf8746 Change-Id: Ie219247e1fd0fd92407c04d5d775a685a13467c4 --- ...ractBluetoothA2dpPreferenceController.java | 225 ------------------ ...BluetoothA2dpPreferenceControllerTest.java | 161 ------------- 2 files changed, 386 deletions(-) delete mode 100644 src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java diff --git a/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java b/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java deleted file mode 100644 index 09f3871cf78..00000000000 --- a/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceController.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2017 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.BluetoothA2dp; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothCodecConfig; -import android.bluetooth.BluetoothCodecStatus; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothManager; -import android.bluetooth.BluetoothProfile; -import android.content.Context; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnDestroy; -import com.android.settingslib.development.DeveloperOptionsPreferenceController; - -import java.util.List; - -public abstract class AbstractBluetoothA2dpPreferenceController extends - DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener, - PreferenceControllerMixin, BluetoothServiceConnectionListener, LifecycleObserver, - OnDestroy { - - @VisibleForTesting - static final int STREAMING_LABEL_ID = - com.android.settingslib.R.string.bluetooth_select_a2dp_codec_streaming_label; - - protected final BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - protected BluetoothA2dp mBluetoothA2dp; - protected ListPreference mPreference; - private final String[] mListValues; - private final String[] mListSummaries; - - @VisibleForTesting - BluetoothAdapter mBluetoothAdapter; - - public AbstractBluetoothA2dpPreferenceController(Context context, Lifecycle lifecycle, - BluetoothA2dpConfigStore store) { - super(context); - - mBluetoothA2dpConfigStore = store; - mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter(); - mListValues = getListValues(); - mListSummaries = getListSummaries(); - - if (lifecycle != null) { - lifecycle.addObserver(this); - } - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - - mPreference = screen.findPreference(getPreferenceKey()); - - // Set a default value because BluetoothCodecConfig is null initially. - mPreference.setValue(mListValues[getDefaultIndex()]); - mPreference.setSummary(mListSummaries[getDefaultIndex()]); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (mBluetoothA2dp == null) { - return false; - } - - writeConfigurationValues(newValue); - - final BluetoothCodecConfig codecConfig = mBluetoothA2dpConfigStore.createCodecConfig(); - synchronized (mBluetoothA2dpConfigStore) { - BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null) { - return false; - } - setCodecConfigPreference(activeDevice, codecConfig); - } - // Because the setting is not persisted into permanent storage, we cannot call update state - // here to update the preference. - // Instead, we just assume it was set and update the preference here. - final int index = mPreference.findIndexOfValue(newValue.toString()); - // We only want to append "Streaming" if not using default - if (index == getDefaultIndex()) { - mPreference.setSummary(mListSummaries[index]); - } else { - mPreference.setSummary( - mContext.getResources().getString(STREAMING_LABEL_ID, mListSummaries[index])); - } - return true; - } - - @Override - public void updateState(Preference preference) { - BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null || getCodecConfig(activeDevice) == null || mPreference == null) { - return; - } - - BluetoothCodecConfig codecConfig; - synchronized (mBluetoothA2dpConfigStore) { - codecConfig = getCodecConfig(activeDevice); - } - - final int index = getCurrentA2dpSettingIndex(codecConfig); - mPreference.setValue(mListValues[index]); - - // We only want to append "Streaming" if not using default - if (index == getDefaultIndex()) { - mPreference.setSummary(mListSummaries[index]); - } else { - mPreference.setSummary( - mContext.getResources().getString(STREAMING_LABEL_ID, mListSummaries[index])); - } - - writeConfigurationValues(mListValues[index]); - } - - @Override - public void onBluetoothServiceConnected(BluetoothA2dp bluetoothA2dp) { - mBluetoothA2dp = bluetoothA2dp; - updateState(mPreference); - } - - @Override - public void onBluetoothCodecUpdated() { - // intentional no-op - // We do not want to call update state here because the setting is not persisted in - // permanent storage. - } - - @Override - public void onBluetoothServiceDisconnected() { - mBluetoothA2dp = null; - } - - @Override - public void onDestroy() { - mBluetoothA2dp = null; - } - - /** - * @return an array of string values that correspond to the current {@link ListPreference}. - */ - protected abstract String[] getListValues(); - - /** - * @return an array of string summaries that correspond to the current {@link ListPreference}. - */ - protected abstract String[] getListSummaries(); - - /** - * Updates the new value to the {@link BluetoothA2dpConfigStore} and the {@link BluetoothA2dp}. - * - * @param newValue the new setting value - */ - protected abstract void writeConfigurationValues(Object newValue); - - /** - * @return the current selected index for the {@link ListPreference}. - */ - protected abstract int getCurrentA2dpSettingIndex(BluetoothCodecConfig config); - - /** - * @return default setting index for the {@link ListPreference}. - */ - protected abstract int getDefaultIndex(); - - @VisibleForTesting - void setCodecConfigPreference(BluetoothDevice device, - BluetoothCodecConfig config) { - BluetoothDevice bluetoothDevice = - (device != null) ? device : getA2dpActiveDevice(); - if (bluetoothDevice == null) { - return; - } - mBluetoothA2dp.setCodecConfigPreference(bluetoothDevice, config); - } - - @VisibleForTesting - BluetoothCodecConfig getCodecConfig(BluetoothDevice device) { - if (mBluetoothA2dp != null) { - BluetoothDevice bluetoothDevice = - (device != null) ? device : getA2dpActiveDevice(); - if (bluetoothDevice == null) { - return null; - } - BluetoothCodecStatus codecStatus = mBluetoothA2dp.getCodecStatus(bluetoothDevice); - if (codecStatus != null) { - return codecStatus.getCodecConfig(); - } - } - return null; - } - - private BluetoothDevice getA2dpActiveDevice() { - if (mBluetoothAdapter == null) { - return null; - } - List activeDevices = - mBluetoothAdapter.getActiveDevices(BluetoothProfile.A2DP); - return (activeDevices.size() > 0) ? activeDevices.get(0) : null; - } -} diff --git a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java deleted file mode 100644 index 783c2edb0f9..00000000000 --- a/tests/robotests/src/com/android/settings/development/AbstractBluetoothA2dpPreferenceControllerTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2017 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 com.android.settings.development.AbstractBluetoothA2dpPreferenceController - .STREAMING_LABEL_ID; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; -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.BluetoothCodecConfig; -import android.content.Context; - -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.ListPreference; -import androidx.preference.PreferenceScreen; - -import com.android.settingslib.core.lifecycle.Lifecycle; - -import org.junit.Before; -import org.junit.Ignore; -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 AbstractBluetoothA2dpPreferenceControllerTest { - - @Mock - private BluetoothA2dp mBluetoothA2dp; - @Mock - private BluetoothCodecConfig mBluetoothCodecConfig; - @Mock - private ListPreference mPreference; - @Mock - private PreferenceScreen mScreen; - @Mock - private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; - private Context mContext; - private AbstractBluetoothA2dpPreferenceController mController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); - mController = spy(new AbstractBluetoothA2dpPreferenceControllerImpl(mContext, mLifecycle, - mBluetoothA2dpConfigStore)); - mController.mBluetoothAdapter = null; - doReturn(mBluetoothCodecConfig).when(mController).getCodecConfig(null); - doNothing().when(mController).setCodecConfigPreference(any(), any()); - when(mBluetoothA2dpConfigStore.createCodecConfig()).thenReturn(mBluetoothCodecConfig); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - mController.displayPreference(mScreen); - } - - @Test - @Ignore - public void onPreferenceChange_bluetoothConnected_shouldUpdateCodec() { - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.onPreferenceChange(mPreference, "" /* new value */); - - verify(mController).setCodecConfigPreference(any(), any()); - } - - @Test - public void onPreferenceChange_bluetoothNotConnected_shouldNotUpdateCodec() { - mController.onBluetoothServiceDisconnected(); - - mController.onPreferenceChange(mPreference, "" /* new value */); - - verify(mController, never()).setCodecConfigPreference(any(), any()); - } - - @Test - @Ignore - public void updateState_option2Set_shouldUpdateToOption2() { - when(mBluetoothCodecConfig.getSampleRate()).thenReturn( - BluetoothCodecConfig.SAMPLE_RATE_48000); - - doReturn(2).when(mController).getCurrentA2dpSettingIndex(any()); - mController.updateState(mPreference); - - verify(mPreference).setValue(mController.getListValues()[2]); - verify(mPreference).setSummary(mContext.getString(STREAMING_LABEL_ID, - mController.getListSummaries()[2])); - } - - @Test - public void onBluetoothServiceConnected_shouldUpdateState() { - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - verify(mController).updateState(mPreference); - } - - private static class AbstractBluetoothA2dpPreferenceControllerImpl - extends AbstractBluetoothA2dpPreferenceController { - - private AbstractBluetoothA2dpPreferenceControllerImpl(Context context, - Lifecycle lifecycle, BluetoothA2dpConfigStore store) { - super(context, lifecycle, store); - } - - @Override - public String getPreferenceKey() { - return null; - } - - @Override - protected String[] getListValues() { - return new String[]{"1", "2", "3"}; - } - - @Override - protected String[] getListSummaries() { - return new String[]{"foo", "bar", "foobar"}; - } - - @Override - protected void writeConfigurationValues(Object newValue) { - } - - @Override - protected int getCurrentA2dpSettingIndex(BluetoothCodecConfig config) { - return 0; - } - - @Override - protected int getDefaultIndex() { - return 0; - } - } -} From 1dda4f5526a70ed274af0411dc0704eb141e4f2a Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Fri, 10 Jan 2025 08:06:55 +0000 Subject: [PATCH 10/12] 24Q4: Removal of a2dp_offload_codec_extensibility_settings Bug: 323319530 Fix: 323319530 Flag: EXEMPT removing com.android.settings.development.a2dp_offload_codec_extensibility_settings Test: atest SettingsRoboTests Merged-In: If9c710c0aaed7326b32dd2e7d5f3109de4047b97 Change-Id: I3fad2d0b5b356afd3524ef9ddc0cf1ccbaed9eb4 --- .../settings_core_flag_declarations.aconfig | 7 - res/layout/bluetooth_audio_codec_dialog.xml | 75 ----- res/xml/development_settings.xml | 8 - .../development/BluetoothA2dpConfigStore.java | 28 +- .../DevelopmentSettingsDashboardFragment.java | 6 +- ...ctBluetoothDialogPreferenceController.java | 2 +- .../BluetoothCodecDialogPreference.java | 77 ----- ...etoothCodecDialogPreferenceController.java | 207 ------------- ...luetoothCodecListPreferenceController.java | 14 +- ...uetoothDialogPreferenceControllerTest.java | 2 +- ...thCodecDialogPreferenceControllerTest.java | 279 ------------------ .../BluetoothCodecDialogPreferenceTest.java | 50 ---- ...oothCodecListPreferenceControllerTest.java | 26 +- 13 files changed, 23 insertions(+), 758 deletions(-) delete mode 100644 res/layout/bluetooth_audio_codec_dialog.xml delete mode 100644 src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreference.java delete mode 100644 src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java diff --git a/aconfig/development/settings_core_flag_declarations.aconfig b/aconfig/development/settings_core_flag_declarations.aconfig index fec67f6b782..b73b0268009 100644 --- a/aconfig/development/settings_core_flag_declarations.aconfig +++ b/aconfig/development/settings_core_flag_declarations.aconfig @@ -1,13 +1,6 @@ package: "com.android.settings.development" container: "system" -flag { - name: "a2dp_offload_codec_extensibility_settings" - namespace: "bluetooth" - description: "Feature flag for Bluetooth Audio Codec extensibility in Settings" - bug: "323319530" -} - flag { name: "deprecate_list_activity" namespace: "android_settings" diff --git a/res/layout/bluetooth_audio_codec_dialog.xml b/res/layout/bluetooth_audio_codec_dialog.xml deleted file mode 100644 index 3a260a655e7..00000000000 --- a/res/layout/bluetooth_audio_codec_dialog.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 7fa514c0c2d..2beb96d8042 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -429,14 +429,6 @@ android:key="bluetooth_hd_audio_settings" android:title="@string/bluetooth_profile_a2dp_high_quality_unknown_codec"/> - - getSelectableIndex() { - List index = new ArrayList<>(); - final BluetoothA2dp bluetoothA2dp = mBluetoothA2dp; - - index.add(getDefaultIndex()); - if (bluetoothA2dp == null) { - return index; - } - final BluetoothDevice activeDevice = getA2dpActiveDevice(); - if (activeDevice == null) { - Log.d(TAG, "Unable to get selectable index. No Active Bluetooth device"); - return index; - } - // Check HD audio is enabled, display the available list. - if (bluetoothA2dp.isOptionalCodecsEnabled(activeDevice) - == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) { - List configs = getSelectableConfigs(activeDevice); - if (configs != null) { - return getIndexFromConfig(configs); - } - } - // If HD audio is disabled, SBC is the only one available codec. - index.add(convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)); - return index; - } - - @Override - protected void writeConfigurationValues(final int index) { - int codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; // default - int codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; - switch (index) { - case 0: - final BluetoothDevice activeDevice = getA2dpActiveDevice(); - codecTypeValue = getHighestCodec(mBluetoothA2dp, activeDevice, - getSelectableConfigs(activeDevice)); - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 1: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 2: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 3: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 4: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 5: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 6: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - case 7: - codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS; - codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST; - break; - default: - break; - } - mBluetoothA2dpConfigStore.setCodecType(codecTypeValue); - mBluetoothA2dpConfigStore.setCodecPriority(codecPriorityValue); - - // Once user changes codec, to reset configs with highest quality. - final BluetoothCodecConfig config = getSelectableByCodecType(codecTypeValue); - if (config == null) { - Log.d(TAG, "Selectable config is null. Unable to reset"); - } - mBluetoothA2dpConfigStore.setSampleRate(getHighestSampleRate(config)); - mBluetoothA2dpConfigStore.setBitsPerSample(getHighestBitsPerSample(config)); - mBluetoothA2dpConfigStore.setChannelMode(getHighestChannelMode(config)); - } - - @Override - protected int getCurrentIndexByConfig(BluetoothCodecConfig config) { - if (config == null) { - Log.e(TAG, "Unable to get current config index. Config is null."); - } - return convertCfgToBtnIndex(config.getCodecType()); - } - - @Override - public void onIndexUpdated(int index) { - super.onIndexUpdated(index); - mCallback.onBluetoothCodecChanged(); - } - - @Override - public void onHDAudioEnabled(boolean enabled) { - writeConfigurationValues(/* index= */ 0); - } - - private List getIndexFromConfig(List configs) { - List indexArray = new ArrayList<>(); - for (BluetoothCodecConfig config : configs) { - indexArray.add(convertCfgToBtnIndex(config.getCodecType())); - } - return indexArray; - } - - @VisibleForTesting - int convertCfgToBtnIndex(int config) { - int index = getDefaultIndex(); - switch (config) { - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC: - index = 1; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC: - index = 2; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX: - index = 3; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD: - index = 4; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC: - index = 5; - break; - case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: - index = 7; - break; - default: - Log.e(TAG, "Unsupported config:" + config); - break; - } - return index; - } -} diff --git a/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java b/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java index 72da5053a69..11ed93cbd46 100644 --- a/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java +++ b/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceController.java @@ -32,7 +32,6 @@ 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; import java.util.ArrayList; @@ -62,9 +61,7 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre @Override public boolean isAvailable() { - boolean available = Flags.a2dpOffloadCodecExtensibilitySettings(); - Log.d(TAG, "isAvailable: " + available); - return available; + return true; } @Override @@ -80,10 +77,6 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre @Override public boolean onPreferenceChange(@Nullable Preference preference, @NonNull Object newValue) { - if (!Flags.a2dpOffloadCodecExtensibilitySettings()) { - return false; - } - if (mListPreference == null) { Log.e(TAG, "onPreferenceChange: List preference is null"); return false; @@ -115,7 +108,7 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre } BluetoothCodecConfig codecConfig = - mBluetoothA2dpConfigStore.createCodecConfigFromCodecType(); + mBluetoothA2dpConfigStore.createCodecConfig(); Log.d(TAG, "onPreferenceChange: setCodecConfigPreference: " + codecConfig.toString()); bluetoothA2dp.setCodecConfigPreference(activeDevice, codecConfig); if (mCallback != null) { @@ -128,9 +121,6 @@ public class BluetoothCodecListPreferenceController extends AbstractBluetoothPre @Override public void updateState(@Nullable Preference preference) { super.updateState(preference); - if (!Flags.a2dpOffloadCodecExtensibilitySettings()) { - return; - } if (!isHDAudioEnabled()) { Log.d(TAG, "updateState: HD Audio is disabled"); diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java index 42b889cfa1a..9825c994374 100644 --- a/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/bluetooth/AbstractBluetoothDialogPreferenceControllerTest.java @@ -220,7 +220,7 @@ public class AbstractBluetoothDialogPreferenceControllerTest { mActiveDevice)).thenReturn(mCodecStatus); mController.onBluetoothServiceConnected(mBluetoothA2dp); - verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getCodecType()); + verify(mBluetoothA2dpConfigStore).setCodecType(mCodecConfigAAC.getExtendedCodecType()); verify(mBluetoothA2dpConfigStore).setSampleRate(mCodecConfigAAC.getSampleRate()); verify(mBluetoothA2dpConfigStore).setBitsPerSample(mCodecConfigAAC.getBitsPerSample()); verify(mBluetoothA2dpConfigStore).setChannelMode(mCodecConfigAAC.getChannelMode()); diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java deleted file mode 100644 index de2b363ed9b..00000000000 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceControllerTest.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (C) 2019 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 com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.atLeastOnce; -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.PreferenceScreen; - -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.Arrays; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class BluetoothCodecDialogPreferenceControllerTest { - - private static final String DEVICE_ADDRESS = "00:11:22:33:44:55"; - - @Mock - private BluetoothA2dp mBluetoothA2dp; - @Mock - private BluetoothAdapter mBluetoothAdapter; - @Mock - private PreferenceScreen mScreen; - @Mock - private AbstractBluetoothPreferenceController.Callback mCallback; - - private BluetoothCodecDialogPreferenceController mController; - private BluetoothCodecDialogPreference mPreference; - private BluetoothA2dpConfigStore mBluetoothA2dpConfigStore; - private BluetoothCodecStatus mCodecStatus; - private BluetoothCodecConfig mCodecConfigAAC; - private BluetoothCodecConfig mCodecConfigSBC; - private BluetoothCodecConfig mCodecConfigAPTX; - private BluetoothCodecConfig mCodecConfigAPTXHD; - private BluetoothCodecConfig mCodecConfigLDAC; - private BluetoothCodecConfig mCodecConfigOPUS; - 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 = new BluetoothCodecDialogPreferenceController(mContext, mLifecycle, - mBluetoothA2dpConfigStore, mCallback); - mController.mBluetoothAdapter = mBluetoothAdapter; - mPreference = new BluetoothCodecDialogPreference(mContext); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - mController.displayPreference(mScreen); - mCodecConfigSBC = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_96000 - | BluetoothCodecConfig.SAMPLE_RATE_176400) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_32) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_MONO - | BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .build(); - mCodecConfigAAC = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) - .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST) - .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000 - | BluetoothCodecConfig.SAMPLE_RATE_88200) - .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16 - | BluetoothCodecConfig.BITS_PER_SAMPLE_24) - .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO) - .build(); - mCodecConfigAPTX = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) - .build(); - mCodecConfigAPTXHD = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) - .build(); - mCodecConfigLDAC = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) - .build(); - mCodecConfigOPUS = new BluetoothCodecConfig.Builder() - .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) - .build(); - when(mBluetoothAdapter.getActiveDevices(eq(BluetoothProfile.A2DP))) - .thenReturn(Arrays.asList(mActiveDevice)); - } - - @Test - public void writeConfigurationValues_selectDefault_setHighest() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC, - mCodecConfigSBC}; - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigSBC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( - BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.writeConfigurationValues(0); - verify(mBluetoothA2dpConfigStore).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS); - } - - @Test - public void writeConfigurationValues_checkCodec() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigOPUS, mCodecConfigAAC, - mCodecConfigSBC, mCodecConfigAPTX, mCodecConfigAPTXHD, mCodecConfigLDAC}; - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigSBC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.writeConfigurationValues(1); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC); - - mController.writeConfigurationValues(2); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC); - - mController.writeConfigurationValues(3); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX); - - mController.writeConfigurationValues(4); - verify(mBluetoothA2dpConfigStore).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD); - - mController.writeConfigurationValues(5); - verify(mBluetoothA2dpConfigStore).setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC); - - mController.writeConfigurationValues(7); - verify(mBluetoothA2dpConfigStore).setCodecType( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS); - } - - @Test - public void writeConfigurationValues_resetHighestConfig() { - BluetoothCodecConfig[] mCodecConfigs = {mCodecConfigAAC, mCodecConfigSBC, mCodecConfigAPTX, - mCodecConfigAPTXHD, mCodecConfigLDAC, mCodecConfigOPUS}; - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigAAC) - .setCodecsSelectableCapabilities(Arrays.asList(mCodecConfigs)) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - mController.writeConfigurationValues(2); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecPriority( - BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setSampleRate( - BluetoothCodecConfig.SAMPLE_RATE_88200); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setBitsPerSample( - BluetoothCodecConfig.BITS_PER_SAMPLE_24); - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setChannelMode( - BluetoothCodecConfig.CHANNEL_MODE_STEREO); - } - - @Test - public void getCurrentIndexByConfig_verifyIndex() { - assertThat(mController.getCurrentIndexByConfig(mCodecConfigAAC)).isEqualTo( - mController.convertCfgToBtnIndex(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)); - } - - @Test - public void getCurrentIndexByConfig_verifyOpusIndex() { - assertThat(mController.getCurrentIndexByConfig(mCodecConfigOPUS)).isEqualTo( - mController.convertCfgToBtnIndex( - BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)); - } - - - @Test - public void onIndexUpdated_notifyPreference() { - mController.onIndexUpdated(0); - - verify(mCallback).onBluetoothCodecChanged(); - } - - @Test - public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsOpus() { - List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, - mCodecConfigAAC, mCodecConfigSBC); - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigOPUS) - .setCodecsSelectableCapabilities(mCodecConfigs) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( - BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.onHDAudioEnabled(/* enabled= */ true); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)); - } - - @Test - public void onHDAudioEnabled_optionalCodecEnabled_setsCodecTypeAsAAC() { - List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, - mCodecConfigAAC, mCodecConfigSBC); - 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); - - mController.onHDAudioEnabled(/* enabled= */ true); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)); - } - @Test - public void onHDAudioEnabled_optionalCodecDisabled_setsCodecTypeAsSBC() { - List mCodecConfigs = Arrays.asList(mCodecConfigOPUS, - mCodecConfigAAC, mCodecConfigSBC); - mCodecStatus = new BluetoothCodecStatus.Builder() - .setCodecConfig(mCodecConfigAAC) - .setCodecsSelectableCapabilities(mCodecConfigs) - .build(); - when(mBluetoothA2dp.getCodecStatus(mActiveDevice)).thenReturn(mCodecStatus); - when(mBluetoothA2dp.isOptionalCodecsEnabled(mActiveDevice)).thenReturn( - BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED); - mController.onBluetoothServiceConnected(mBluetoothA2dp); - - mController.onHDAudioEnabled(/* enabled= */ false); - - verify(mBluetoothA2dpConfigStore, atLeastOnce()).setCodecType( - eq(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)); - } -} diff --git a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java deleted file mode 100644 index 4b8df164fe6..00000000000 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecDialogPreferenceTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2019 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 com.google.common.truth.Truth.assertThat; - -import android.content.Context; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class BluetoothCodecDialogPreferenceTest { - - private BluetoothCodecDialogPreference mPreference; - private Context mContext; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mPreference = new BluetoothCodecDialogPreference(mContext); - } - - @Test - public void getRadioButtonGroupId() { - assertThat(mPreference.getRadioButtonGroupId()) - .isEqualTo(R.id.bluetooth_audio_codec_radio_group); - } -} 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 4ac5dff1eef..a99dc2b1f55 100644 --- a/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/bluetooth/BluetoothCodecListPreferenceControllerTest.java @@ -18,7 +18,6 @@ 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; @@ -35,14 +34,12 @@ import android.bluetooth.BluetoothCodecType; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; -import android.platform.test.annotations.EnableFlags; import androidx.lifecycle.LifecycleOwner; import androidx.preference.ListPreference; import androidx.preference.PreferenceScreen; import com.android.settings.development.BluetoothA2dpConfigStore; -import com.android.settings.development.Flags; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; @@ -73,6 +70,7 @@ public class BluetoothCodecListPreferenceControllerTest { private BluetoothCodecType mCodecTypeAAC; private BluetoothCodecType mCodecTypeSBC; private BluetoothCodecType mCodecTypeAPTX; + private BluetoothCodecType mCodecTypeAPTXHD; private BluetoothCodecType mCodecTypeLDAC; private BluetoothCodecType mCodecTypeOPUS; private List mCodecTypes; @@ -114,6 +112,8 @@ public class BluetoothCodecListPreferenceControllerTest { BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC); mCodecTypeAPTX = BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX); + mCodecTypeAPTXHD = + BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD); mCodecTypeLDAC = BluetoothCodecType.createFromType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC); mCodecTypeOPUS = @@ -125,6 +125,7 @@ public class BluetoothCodecListPreferenceControllerTest { mCodecTypeSBC, mCodecTypeAAC, mCodecTypeAPTX, + mCodecTypeAPTXHD, mCodecTypeLDAC, mCodecTypeOPUS)); @@ -212,6 +213,11 @@ public class BluetoothCodecListPreferenceControllerTest { mController.writeConfigurationValues(String.valueOf(mCodecTypeAPTX.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTX); + assertTrue( + mController.writeConfigurationValues(String.valueOf( + mCodecTypeAPTXHD.getCodecId()))); + verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeAPTXHD); + assertTrue( mController.writeConfigurationValues(String.valueOf(mCodecTypeLDAC.getCodecId()))); verify(mBluetoothA2dpConfigStore).setCodecType(mCodecTypeLDAC); @@ -244,7 +250,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onPreferenceChange_notifyPreference() { assertFalse( mController.onPreferenceChange( @@ -271,7 +276,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onPreferenceChange_listPreferenceIsNull() { when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(null); assertFalse( @@ -280,13 +284,11 @@ public class BluetoothCodecListPreferenceControllerTest { } @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)) @@ -325,6 +327,14 @@ public class BluetoothCodecListPreferenceControllerTest { assertTrue( mController.onPreferenceChange( mPreference, String.valueOf(mCodecTypeAPTX.getCodecId()))); + mCodecStatus = + new BluetoothCodecStatus.Builder() + .setCodecConfig(mCodecConfigAPTXHD) + .setCodecsSelectableCapabilities(mCodecConfigs) + .build(); + assertTrue( + mController.onPreferenceChange( + mPreference, String.valueOf(mCodecTypeAPTXHD.getCodecId()))); mCodecStatus = new BluetoothCodecStatus.Builder() .setCodecConfig(mCodecConfigOPUS) @@ -336,7 +346,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void updateState_notifyPreference() { assertFalse( mController.onPreferenceChange( @@ -437,7 +446,6 @@ public class BluetoothCodecListPreferenceControllerTest { } @Test - @EnableFlags(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY_SETTINGS) public void onBluetoothServiceConnected_verifyBluetoothA2dpConfigStore() { mCodecStatus = new BluetoothCodecStatus.Builder() From 27e4fcc6c69f641e6edb75ddfaca23ebe827bdf1 Mon Sep 17 00:00:00 2001 From: Yiyi Shen Date: Wed, 15 Jan 2025 15:25:32 +0800 Subject: [PATCH 11/12] [Audiosharing] Use setBroadcastToUnicastFallbackGroup to set primary Flag: com.android.settingslib.flags.adopt_primary_group_management_api Test: atest Bug: 381946931 Change-Id: Ib06dd2e202b07b9cdb25b1a671ee4d57246415ba --- ...oSharingCallAudioPreferenceController.java | 55 +++++++++++++------ ...udioSharingDevicePreferenceController.java | 3 +- .../AudioSharingDialogHandler.java | 3 +- .../audiosharing/AudioSharingUtils.java | 5 +- ...ringCallAudioPreferenceControllerTest.java | 46 +++++++++++++--- ...SharingDevicePreferenceControllerTest.java | 2 + .../AudioSharingDialogHandlerTest.java | 3 + 7 files changed, 88 insertions(+), 29 deletions(-) diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java index 3130a0c3600..25180d8dbc4 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java @@ -16,6 +16,8 @@ package com.android.settings.connecteddevice.audiosharing; +import static com.android.settingslib.Utils.isAudioModeOngoingCall; + import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothCsipSetCoordinator; @@ -48,6 +50,7 @@ import com.android.settingslib.bluetooth.BluetoothEventManager; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; @@ -91,6 +94,7 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP Map> mGroupedConnectedDevices = new HashMap<>(); private List mDeviceItemsInSharingSession = new ArrayList<>(); private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false); + private AtomicBoolean mIsAudioModeOngoingCall = new AtomicBoolean(false); @VisibleForTesting final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = @@ -202,28 +206,15 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP mDeviceItemsInSharingSession, pair == null ? -1 : pair.first, (AudioSharingDeviceItem item) -> { - int currentGroupId = + int currentCallAudioGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast( mContext.getContentResolver()); int clickedGroupId = item.getGroupId(); - if (clickedGroupId == currentGroupId) { + if (clickedGroupId == currentCallAudioGroupId) { Log.d(TAG, "Skip set call audio device: unchanged"); return; } - List devices = - mGroupedConnectedDevices.getOrDefault( - clickedGroupId, ImmutableList.of()); - CachedBluetoothDevice lead = - AudioSharingUtils.getLeadDevice( - mCacheManager, devices); - if (lead != null) { - String addr = lead.getDevice().getAnonymizedAddress(); - Log.d(TAG, "Set call audio device: " + addr); - AudioSharingUtils.setPrimary(mContext, lead); - logCallAudioDeviceChange(currentGroupId, lead); - } else { - Log.d(TAG, "Skip set call audio device: no lead"); - } + setCallAudioGroup(clickedGroupId); }); } return true; @@ -269,6 +260,11 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP } } + @Override + public void onAudioModeChanged() { + mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext)); + } + /** * Initialize the controller. * @@ -311,6 +307,7 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP false, mSettingsObserver); mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); + mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext)); mCallbacksRegistered.set(true); } } @@ -333,6 +330,32 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP } } + private void setCallAudioGroup(int groupId) { + List devices = + mGroupedConnectedDevices.getOrDefault( + groupId, ImmutableList.of()); + CachedBluetoothDevice lead = + AudioSharingUtils.getLeadDevice( + mCacheManager, devices); + if (lead != null) { + String addr = lead.getDevice().getAnonymizedAddress(); + Log.d(TAG, "Set call audio device: " + addr); + if (Flags.adoptPrimaryGroupManagementApi() && !mIsAudioModeOngoingCall.get()) { + LeAudioProfile leaProfile = mBtManager == null ? null + : mBtManager.getProfileManager().getLeAudioProfile(); + if (leaProfile != null) { + leaProfile.setBroadcastToUnicastFallbackGroup(groupId); + } + } else { + lead.setActive(); + } + AudioSharingUtils.setUserPreferredPrimary(mContext, lead); + logCallAudioDeviceChange(groupId, lead); + } else { + Log.d(TAG, "Skip set call audio device: no lead"); + } + } + /** * Update the preference summary: current headset for call audio. * diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java index c286ed6114e..ffbb13e9808 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java @@ -389,7 +389,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro Log.d(TAG, "onDeviceClick, set active in call mode"); CachedBluetoothDevice cachedDevice = ((BluetoothDevicePreference) preference).getBluetoothDevice(); - AudioSharingUtils.setPrimary(mContext, cachedDevice); + cachedDevice.setActive(); + AudioSharingUtils.setUserPreferredPrimary(mContext, cachedDevice); } mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK, isCallMode); diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java index 0c3448729b8..2a1f4da2cf8 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java @@ -192,7 +192,8 @@ public class AudioSharingDialogHandler { // If this method is called with user triggered, e.g. manual click on the // "Connected devices" page, we need call setActive for the device, since user // intend to switch active device for the call. - AudioSharingUtils.setPrimary(mContext, cachedDevice); + cachedDevice.setActive(); + AudioSharingUtils.setUserPreferredPrimary(mContext, cachedDevice); } return; } diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java index 5a15b6ae51c..7824b262d0d 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java @@ -346,11 +346,10 @@ public class AudioSharingUtils { return vc != null && vc.isProfileReady(); } - /** Set {@link CachedBluetoothDevice} as primary device for call audio */ - public static void setPrimary( + /** Set {@link CachedBluetoothDevice} as user preferred primary device for call audio */ + public static void setUserPreferredPrimary( @NonNull Context context, @Nullable CachedBluetoothDevice cachedDevice) { if (cachedDevice == null) return; - cachedDevice.setActive(); if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context)) { int groupId = BluetoothUtils.getGroupId(cachedDevice); // TODO: use real key name in SettingsProvider diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java index 3075573b728..a2ac0cc99c9 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java @@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -67,6 +68,7 @@ import com.android.settingslib.bluetooth.BluetoothEventManager; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; @@ -77,7 +79,6 @@ import com.android.settingslib.flags.Flags; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.junit.After; import org.junit.Before; @@ -89,8 +90,10 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowListView; import org.robolectric.shadows.androidx.fragment.FragmentController; import java.util.ArrayList; @@ -483,19 +486,46 @@ public class AudioSharingCallAudioPreferenceControllerTest { AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); assertThat(dialog.isShowing()).isTrue(); assertThat(dialog.getListView().getCount()).isEqualTo(2); - ArrayList outViews = new ArrayList<>(); - dialog.getListView() - .findViewsWithText(outViews, TEST_DEVICE_NAME1, View.FIND_VIEWS_WITH_TEXT); - assertThat(outViews.size()).isEqualTo(1); - View view = Iterables.getOnlyElement(outViews); - assertThat(view instanceof CheckedTextView).isTrue(); - assertThat(((CheckedTextView) view).isChecked()).isTrue(); + ShadowListView listView = Shadows.shadowOf(dialog.getListView()); + View view1 = listView.findItemContainingText(TEST_DEVICE_NAME1); + assertThat(view1).isNotNull(); + assertThat(view1 instanceof CheckedTextView).isTrue(); + assertThat(((CheckedTextView) view1).isChecked()).isTrue(); + View view2 = listView.findItemContainingText(TEST_DEVICE_NAME2); + assertThat(view2).isNotNull(); + assertThat(view2 instanceof CheckedTextView).isTrue(); + assertThat(((CheckedTextView) view2).isChecked()).isFalse(); + verify(mFeatureFactory.metricsFeatureProvider) .visible( /* context= */ eq(null), /* source= */ anyInt(), eq(SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO), /* latency= */ anyInt()); + + LeAudioProfile leAudioProfile = mock(LeAudioProfile.class); + when(mBtProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile); + + // Perform click to switch call audio device by set active + mSetFlagsRule.disableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); + int index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME2); + listView.performItemClick(index); + shadowOf(Looper.getMainLooper()).idle(); + assertThat(((CheckedTextView) view1).isChecked()).isFalse(); + assertThat(((CheckedTextView) view2).isChecked()).isTrue(); + verify(mCachedDevice3).setActive(); + verify(leAudioProfile, never()).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID2); + + // Perform click to switch call audio device with API + mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); + Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID2); + index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME1); + listView.performItemClick(index); + shadowOf(Looper.getMainLooper()).idle(); + assertThat(((CheckedTextView) view1).isChecked()).isTrue(); + assertThat(((CheckedTextView) view2).isChecked()).isFalse(); + verify(mCachedDevice1, never()).setActive(); + verify(leAudioProfile).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID1); } @Test diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java index a49d0c13890..4a4a167622f 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java @@ -584,6 +584,7 @@ public class AudioSharingDevicePreferenceControllerTest { public void testInCallState_showCallStateTitleAndSetActiveOnDeviceClick() { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); Settings.Secure.putInt(mContext.getContentResolver(), BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); @@ -609,6 +610,7 @@ public class AudioSharingDevicePreferenceControllerTest { public void testInCallState_enableHysteresisFix_setAndSaveActiveOnDeviceClick() { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); Settings.Secure.putInt(mContext.getContentResolver(), BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java index c96a08623f8..b609cddfb8c 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java @@ -198,6 +198,7 @@ public class AudioSharingDialogHandlerTest { @Test public void handleUserTriggeredDeviceConnected_inCall_setActive() { mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); Settings.Secure.putInt(mContext.getContentResolver(), BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); @@ -218,6 +219,7 @@ public class AudioSharingDialogHandlerTest { @Test public void handleUserTriggeredDeviceConnected_inCall_enableHysteresisFix_setAndSaveActive() { mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); Settings.Secure.putInt(mContext.getContentResolver(), BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); @@ -452,6 +454,7 @@ public class AudioSharingDialogHandlerTest { @Test public void handleDeviceConnected_inCall_doNothing() { + mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL); setUpBroadcast(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); From ea305dc01e1444962b0c00d63ddb03a4b523c6d9 Mon Sep 17 00:00:00 2001 From: chenjean Date: Wed, 15 Jan 2025 18:15:38 +0800 Subject: [PATCH 12/12] fix(HCT):Ensure HCT Notification ID does not conflict in the Settings app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current HCT notification uses NOTIFICATION_ID=1. The Settings app has a few other notifications also use NOTIFICATION_ID=1 like Bluetooth and Sim etc. When using the same NOTIFICATION_ID for a notification, it updates the existing notification, causing the original one to disappear. To avoid this, we use a unique NOTIFICATION_ID. Bug: 388530317 Flag: EXEMPT resource only update Test: manual Test: atest HighContrastTextMigrationReceiverTest Change-Id: Ieda6836190726b14cd3522f61e7992e5a5698231 --- .../accessibility/HighContrastTextMigrationReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/accessibility/HighContrastTextMigrationReceiver.java b/src/com/android/settings/accessibility/HighContrastTextMigrationReceiver.java index 8e311858f51..a0949cf7b07 100644 --- a/src/com/android/settings/accessibility/HighContrastTextMigrationReceiver.java +++ b/src/com/android/settings/accessibility/HighContrastTextMigrationReceiver.java @@ -57,7 +57,7 @@ public class HighContrastTextMigrationReceiver extends BroadcastReceiver { static final String ACTION_OPEN_SETTINGS = "com.android.settings.accessibility.ACTION_OPEN_HIGH_CONTRAST_TEXT_SETTINGS"; @VisibleForTesting - static final int NOTIFICATION_ID = 1; + static final int NOTIFICATION_ID = R.string.accessibility_notification_high_contrast_text_title; @Retention(RetentionPolicy.SOURCE) @IntDef({