diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java index 5d9b124f28b..42d39487398 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java @@ -26,6 +26,7 @@ import android.sysprop.BluetoothProperties; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; @@ -52,7 +53,9 @@ import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -82,7 +85,9 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll private static final String LE_AUDIO_TOGGLE_VISIBLE_PROPERTY = "persist.bluetooth.leaudio.toggle_visible"; - private final AtomicReference> mInvisiblePreferenceKey = new AtomicReference<>(); + private Set mInvisibleProfiles = Collections.emptySet(); + private final AtomicReference> mAdditionalInvisibleProfiles = + new AtomicReference<>(); private LocalBluetoothManager mManager; private LocalBluetoothProfileManager mProfileManager; @@ -96,13 +101,21 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll @VisibleForTesting PreferenceCategory mProfilesContainer; - public BluetoothDetailsProfilesController(Context context, PreferenceFragmentCompat fragment, - LocalBluetoothManager manager, CachedBluetoothDevice device, Lifecycle lifecycle) { + public BluetoothDetailsProfilesController( + Context context, + PreferenceFragmentCompat fragment, + LocalBluetoothManager manager, + CachedBluetoothDevice device, + Lifecycle lifecycle, + @Nullable List invisibleProfiles) { super(context, fragment, device, lifecycle); mManager = manager; mProfileManager = mManager.getProfileManager(); mCachedDevice = device; mCachedDeviceGroup = Utils.findAllCachedBluetoothDevicesByGroupId(mManager, mCachedDevice); + if (invisibleProfiles != null) { + mInvisibleProfiles = Set.copyOf(invisibleProfiles); + } } @Override @@ -564,7 +577,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll protected void refresh() { ThreadUtils.postOnBackgroundThread( () -> { - mInvisiblePreferenceKey.set( + mAdditionalInvisibleProfiles.set( FeatureFactory.getFeatureFactory() .getBluetoothFeatureProvider() .getInvisibleProfilePreferenceKeys( @@ -605,12 +618,15 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll mProfilesContainer.addPreference(preference); } - Set invisibleKeys = mInvisiblePreferenceKey.get(); - if (invisibleKeys != null) { - for (int i = 0; i < mProfilesContainer.getPreferenceCount(); ++i) { - Preference pref = mProfilesContainer.getPreference(i); - pref.setVisible(pref.isVisible() && !invisibleKeys.contains(pref.getKey())); - } + Set additionalInvisibleProfiles = mAdditionalInvisibleProfiles.get(); + HashSet combinedInvisibleProfiles = new HashSet<>(mInvisibleProfiles); + if (additionalInvisibleProfiles != null) { + combinedInvisibleProfiles.addAll(additionalInvisibleProfiles); + } + Log.i(TAG, "Invisible profiles: " + combinedInvisibleProfiles); + for (int i = 0; i < mProfilesContainer.getPreferenceCount(); ++i) { + Preference pref = mProfilesContainer.getPreference(i); + pref.setVisible(pref.isVisible() && !combinedInvisibleProfiles.contains(pref.getKey())); } } diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java index 844a7c05484..0e51d178fe8 100644 --- a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java +++ b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java @@ -419,12 +419,16 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment @Override protected List createPreferenceControllers(Context context) { + List invisibleProfiles = List.of(); if (Flags.enableBluetoothDeviceDetailsPolish()) { mFormatter = FeatureFactory.getFeatureFactory() .getBluetoothFeatureProvider() .getDeviceDetailsFragmentFormatter( requireContext(), this, mBluetoothAdapter, mCachedDevice); + invisibleProfiles = + mFormatter.getInvisibleBluetoothProfiles( + FragmentTypeModel.DeviceDetailsMainFragment.INSTANCE); } ArrayList controllers = new ArrayList<>(); @@ -444,7 +448,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment controllers.add(new BluetoothDetailsSpatialAudioController(context, this, mCachedDevice, lifecycle)); controllers.add(new BluetoothDetailsProfilesController(context, this, mManager, - mCachedDevice, lifecycle)); + mCachedDevice, lifecycle, invisibleProfiles)); controllers.add(new BluetoothDetailsMacAddressController(context, this, mCachedDevice, lifecycle)); controllers.add(new StylusDevicesController(context, mInputDevice, mCachedDevice, diff --git a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt index 8f0bf3e9dc6..f2a569d2245 100644 --- a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt +++ b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt @@ -43,6 +43,7 @@ import com.android.settings.core.SubSettingLauncher import com.android.settings.overlay.FeatureFactory.Companion.featureFactory import com.android.settings.spa.preference.ComposePreference import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.devicesettings.DeviceSettingId import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigItemModel import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingIcon import com.android.settingslib.spa.framework.theme.SettingsDimension @@ -68,6 +69,9 @@ interface DeviceDetailsFragmentFormatter { /** Gets keys of visible preferences in built-in preference in xml. */ fun getVisiblePreferenceKeys(fragmentType: FragmentTypeModel): List? + /** Updates device details fragment layout. */ + fun getInvisibleBluetoothProfiles(fragmentType: FragmentTypeModel): List? + /** Updates device details fragment layout. */ fun updateLayout(fragmentType: FragmentTypeModel) @@ -108,13 +112,22 @@ class DeviceDetailsFragmentFormatterImpl( viewModel .getItems(fragmentType) ?.filterIsInstance() - ?.mapNotNull { it.preferenceKey } + ?.map { it.preferenceKey } + } + + override fun getInvisibleBluetoothProfiles(fragmentType: FragmentTypeModel): List? = + runBlocking { + viewModel + .getItems(fragmentType) + ?.filterIsInstance() + ?.first()?.invisibleProfiles } /** Updates bluetooth device details fragment layout. */ override fun updateLayout(fragmentType: FragmentTypeModel) = runBlocking { val items = viewModel.getItems(fragmentType) ?: return@runBlocking val layout = viewModel.getLayout(fragmentType) ?: return@runBlocking + val prefKeyToSettingId = items .filterIsInstance() diff --git a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt index f69f023d482..c0fbd4f2c4a 100644 --- a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt +++ b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt @@ -22,7 +22,6 @@ import android.content.Context import android.graphics.PorterDuff import android.os.Bundle import android.view.Menu -import android.view.MenuInflater import android.view.MenuItem import androidx.lifecycle.lifecycleScope import com.android.settings.R @@ -63,8 +62,10 @@ class DeviceDetailsMoreSettingsFragment : DashboardFragment() { item.icon?.setColorFilter( resources.getColor( com.android.settingslib.widget.theme.R.color - .settingslib_materialColorOnSurface), - PorterDuff.Mode.SRC_ATOP) + .settingslib_materialColorOnSurface + ), + PorterDuff.Mode.SRC_ATOP, + ) item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) } } @@ -116,14 +117,27 @@ class DeviceDetailsMoreSettingsFragment : DashboardFragment() { } formatter = featureFactory.bluetoothFeatureProvider.getDeviceDetailsFragmentFormatter( - requireContext(), this, bluetoothManager.adapter, cachedDevice) + requireContext(), + this, + bluetoothManager.adapter, + cachedDevice, + ) helpItem = formatter .getMenuItem(FragmentTypeModel.DeviceDetailsMoreSettingsFragment) .stateIn(lifecycleScope, SharingStarted.WhileSubscribed(), initialValue = null) return listOf( BluetoothDetailsProfilesController( - context, this, localBluetoothManager, cachedDevice, settingsLifecycle)) + context, + this, + localBluetoothManager, + cachedDevice, + settingsLifecycle, + formatter.getInvisibleBluetoothProfiles( + FragmentTypeModel.DeviceDetailsMoreSettingsFragment + ), + ) + ) } override fun getLogTag(): String = TAG diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java index 4b4dd8b11e1..d137d8287e8 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java @@ -120,11 +120,7 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont .thenAnswer(invocation -> ImmutableList.of(mConnectableProfiles)); setupDevice(mDeviceConfig); - mController = new BluetoothDetailsProfilesController(mContext, mFragment, mLocalManager, - mCachedDevice, mLifecycle); - mProfiles.setKey(mController.getPreferenceKey()); - mController.mProfilesContainer = mProfiles; - mScreen.addPreference(mProfiles); + initController(List.of()); BluetoothProperties.le_audio_allow_list(Lists.newArrayList(LE_DEVICE_MODEL)); } @@ -554,6 +550,36 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Test public void prefKeyInBlockingList_hideToggle() { + initController(List.of("A2DP")); + setupDevice(makeDefaultDeviceConfig()); + + addA2dpProfileToDevice(true, true, true); + when(mFeatureProvider.getInvisibleProfilePreferenceKeys(any(), any())) + .thenReturn(ImmutableSet.of()); + + showScreen(mController); + + List switches = getProfileSwitches(false); + assertThat(switches.get(0).isVisible()).isFalse(); + } + + @Test + public void prefKeyNotInBlockingList_showToggle() { + initController(List.of()); + setupDevice(makeDefaultDeviceConfig()); + + addA2dpProfileToDevice(true, true, true); + when(mFeatureProvider.getInvisibleProfilePreferenceKeys(any(), any())) + .thenReturn(ImmutableSet.of()); + + showScreen(mController); + + List switches = getProfileSwitches(false); + assertThat(switches.get(0).isVisible()).isTrue(); + } + + @Test + public void prefKeyInFeatureProviderBlockingList_hideToggle() { setupDevice(makeDefaultDeviceConfig()); addA2dpProfileToDevice(true, true, true); @@ -567,7 +593,7 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont } @Test - public void prefKeyNotInBlockingList_showToggle() { + public void prefKeyNotInFeatureProviderBlockingList_showToggle() { setupDevice(makeDefaultDeviceConfig()); addA2dpProfileToDevice(true, true, true); @@ -627,4 +653,13 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont assertThat(switches.getFirst().getTitle()).isEqualTo( mContext.getString(mLeAudioProfile.getNameResource(mDevice))); } + + private void initController(List invisibleProfiles) { + mController = new BluetoothDetailsProfilesController(mContext, mFragment, mLocalManager, + mCachedDevice, mLifecycle, invisibleProfiles); + mProfiles.setKey(mController.getPreferenceKey()); + mController.mProfilesContainer = mProfiles; + mScreen.removeAll(); + mScreen.addPreference(mProfiles); + } } diff --git a/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt b/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt index a5bc2463cdd..8070b2e5362 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt +++ b/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt @@ -122,10 +122,11 @@ class DeviceDetailsFragmentFormatterTest { .thenReturn( DeviceSettingConfigModel( listOf( - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_HEADER, - "bluetooth_device_header"), - DeviceSettingConfigItemModel.BuiltinItem( + "bluetooth_device_header" + ), + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_ACTION_BUTTONS, "action_buttons"), ), listOf(), @@ -203,10 +204,10 @@ class DeviceDetailsFragmentFormatterTest { .thenReturn( DeviceSettingConfigModel( listOf( - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_HEADER, "bluetooth_device_header"), - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_KEYBOARD_SETTINGS, "keyboard_settings"), ), @@ -227,12 +228,12 @@ class DeviceDetailsFragmentFormatterTest { .thenReturn( DeviceSettingConfigModel( listOf( - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_HEADER, "bluetooth_device_header"), DeviceSettingConfigItemModel.AppProvidedItem( DeviceSettingId.DEVICE_SETTING_ID_ANC), - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_KEYBOARD_SETTINGS, "keyboard_settings"), ), diff --git a/tests/robotests/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModelTest.kt b/tests/robotests/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModelTest.kt index 9cbe6e38736..6869c23fa95 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModelTest.kt +++ b/tests/robotests/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModelTest.kt @@ -282,10 +282,10 @@ class BluetoothDeviceDetailsViewModelTest { private companion object { val BUILTIN_SETTING_ITEM_1 = - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_HEADER, "bluetooth_device_header") val BUILDIN_SETTING_ITEM_2 = - DeviceSettingConfigItemModel.BuiltinItem( + DeviceSettingConfigItemModel.BuiltinItem.CommonBuiltinItem( DeviceSettingId.DEVICE_SETTING_ID_ACTION_BUTTONS, "action_buttons") val SETTING_ITEM_HELP = DeviceSettingConfigItemModel.AppProvidedItem(12345) }