Merge "Fix text is not readable with black & white wallpaper issue" into main
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
index 5ffa8cf..462f422 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
@@ -47,7 +47,7 @@
 
     @Override
     public boolean isAvailable() {
-        boolean hasLeAudio = mCachedDevice.getConnectableProfiles()
+        boolean hasLeAudio = mCachedDevice.getUiAccessibleProfiles()
                 .stream()
                 .anyMatch(profile -> profile.getProfileId() == BluetoothProfile.LE_AUDIO);
         return !BluetoothUtils.isAdvancedDetailsHeader(mCachedDevice.getDevice()) && !hasLeAudio;
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index 50c908d..2b74684 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -314,7 +314,7 @@
             return result;
         }
         for (CachedBluetoothDevice cachedItem : mAllOfCachedDevices) {
-            List<LocalBluetoothProfile> tmpResult = cachedItem.getConnectableProfiles();
+            List<LocalBluetoothProfile> tmpResult = cachedItem.getUiAccessibleProfiles();
             for (LocalBluetoothProfile profile : tmpResult) {
                 if (mProfileDeviceMap.containsKey(profile.toString())) {
                     mProfileDeviceMap.get(profile.toString()).add(cachedItem);
diff --git a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
index a64874d..4be4d63 100644
--- a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
@@ -107,7 +107,7 @@
         if (mCachedDevice == null || mProfileManager == null) {
             return CONDITIONALLY_UNAVAILABLE;
         }
-        boolean hasLeAudio = mCachedDevice.getConnectableProfiles()
+        boolean hasLeAudio = mCachedDevice.getUiAccessibleProfiles()
                 .stream()
                 .anyMatch(profile -> profile.getProfileId() == BluetoothProfile.LE_AUDIO);
 
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index a0c0b44..d6ad4bc 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -437,7 +437,7 @@
     }
 
     private boolean isMediaDevice(CachedBluetoothDevice cachedDevice) {
-        return cachedDevice.getConnectableProfiles().stream()
+        return cachedDevice.getUiAccessibleProfiles().stream()
                 .anyMatch(
                         profile ->
                                 profile instanceof A2dpProfile
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
index 2e93539..548d17c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
@@ -16,13 +16,9 @@
 
 package com.android.settings.connecteddevice.audiosharing;
 
-import android.app.settings.SettingsEnums;
-import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
-import android.media.AudioManager;
 import android.util.Log;
-import android.widget.SeekBar;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
@@ -40,7 +36,7 @@
 public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdater
         implements Preference.OnPreferenceClickListener {
 
-    private static final String TAG = "AudioSharingDeviceVolumeControlUpdater";
+    private static final String TAG = "AudioSharingVolUpdater";
 
     @VisibleForTesting
     static final String PREF_KEY_PREFIX = "audio_sharing_volume_control_";
@@ -91,36 +87,9 @@
         if (cachedDevice == null) return;
         final BluetoothDevice device = cachedDevice.getDevice();
         if (!mPreferenceMap.containsKey(device)) {
-            SeekBar.OnSeekBarChangeListener listener =
-                    new SeekBar.OnSeekBarChangeListener() {
-                        @Override
-                        public void onProgressChanged(
-                                SeekBar seekBar, int progress, boolean fromUser) {}
-
-                        @Override
-                        public void onStartTrackingTouch(SeekBar seekBar) {}
-
-                        @Override
-                        public void onStopTrackingTouch(SeekBar seekBar) {
-                            int progress = seekBar.getProgress();
-                            int groupId = BluetoothUtils.getGroupId(cachedDevice);
-                            if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
-                                    && groupId
-                                            == BluetoothUtils.getPrimaryGroupIdForBroadcast(
-                                                    mContext.getContentResolver())) {
-                                // Set media stream volume for primary buds, audio manager will
-                                // update all buds volume in the audio sharing.
-                                setAudioManagerStreamVolume(progress);
-                            } else {
-                                // Set buds volume for other buds.
-                                setDeviceVolume(cachedDevice, progress);
-                            }
-                        }
-                    };
             AudioSharingDeviceVolumePreference vPreference =
                     new AudioSharingDeviceVolumePreference(mPrefContext, cachedDevice);
             vPreference.initialize();
-            vPreference.setOnSeekBarChangeListener(listener);
             vPreference.setKey(getPreferenceKeyPrefix() + cachedDevice.hashCode());
             vPreference.setIcon(com.android.settingslib.R.drawable.ic_bt_untethered_earbuds);
             vPreference.setTitle(cachedDevice.getName());
@@ -154,35 +123,4 @@
 
     @Override
     public void refreshPreference() {}
-
-    private void setDeviceVolume(CachedBluetoothDevice cachedDevice, int progress) {
-        if (mVolumeControl != null) {
-            mVolumeControl.setDeviceVolume(
-                    cachedDevice.getDevice(), progress, /* isGroupOp= */ true);
-            mMetricsFeatureProvider.action(
-                    mContext,
-                    SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
-                    /* isPrimary= */ false);
-        }
-    }
-
-    private void setAudioManagerStreamVolume(int progress) {
-        int seekbarRange =
-                AudioSharingDeviceVolumePreference.MAX_VOLUME
-                        - AudioSharingDeviceVolumePreference.MIN_VOLUME;
-        try {
-            AudioManager audioManager = mContext.getSystemService(AudioManager.class);
-            int streamVolumeRange =
-                    audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
-                            - audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
-            int volume = Math.round((float) progress * streamVolumeRange / seekbarRange);
-            audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
-            mMetricsFeatureProvider.action(
-                    mContext,
-                    SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
-                    /* isPrimary= */ true);
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Fail to setAudioManagerStreamVolumeForFallbackDevice, error = " + e);
-        }
-    }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
index 48b04b4..42de10a 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
@@ -61,7 +61,7 @@
 
 public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePreferenceController
         implements DevicePreferenceCallback {
-    private static final String TAG = "AudioSharingDeviceVolumeGroupController";
+    private static final String TAG = "AudioSharingVolCtlr";
     private static final String KEY = "audio_sharing_device_volume_group";
 
     @Nullable private final LocalBluetoothManager mBtManager;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreference.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreference.java
index 01afc02..816ec6e 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreference.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreference.java
@@ -16,27 +16,46 @@
 
 package com.android.settings.connecteddevice.audiosharing;
 
+import android.app.settings.SettingsEnums;
+import android.bluetooth.BluetoothCsipSetCoordinator;
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
+import android.media.AudioManager;
+import android.util.Log;
 import android.widget.SeekBar;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.settings.R;
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.VolumeControlProfile;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.utils.ThreadUtils;
 
 public class AudioSharingDeviceVolumePreference extends SeekBarPreference {
+    private static final String TAG = "AudioSharingVolPref";
+
     public static final int MIN_VOLUME = 0;
     public static final int MAX_VOLUME = 255;
 
+    private final Context mContext;
     private final CachedBluetoothDevice mCachedDevice;
     @Nullable protected SeekBar mSeekBar;
+    private Boolean mTrackingTouch = false;
+    private MetricsFeatureProvider mMetricsFeatureProvider =
+            FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
 
     public AudioSharingDeviceVolumePreference(
             Context context, @NonNull CachedBluetoothDevice device) {
         super(context);
         setLayoutResource(R.layout.preference_volume_slider);
+        mContext = context;
         mCachedDevice = device;
     }
 
@@ -54,4 +73,95 @@
         setMax(MAX_VOLUME);
         setMin(MIN_VOLUME);
     }
+
+    @Override
+    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+        super.onProgressChanged(seekBar, progress, fromUser);
+        // When user use talk back swipe up/down or use Switch Access to change the volume bar
+        // progress, there is no onStopTrackingTouch triggered. So we need to check this scenario
+        // and update the device volume here.
+        if (fromUser && !mTrackingTouch) {
+            Log.d(TAG, "onProgressChanged from user and not in touch, handleProgressChange.");
+            handleProgressChange(progress);
+        }
+    }
+
+    @Override
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        mTrackingTouch = true;
+        super.onStartTrackingTouch(seekBar);
+    }
+
+    @Override
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        mTrackingTouch = false;
+        super.onStopTrackingTouch(seekBar);
+        // When user touch the volume bar to change volume, we only update the device volume when
+        // user stop touching the bar.
+        Log.d(TAG, "onStopTrackingTouch, handleProgressChange.");
+        handleProgressChange(seekBar.getProgress());
+    }
+
+    private void handleProgressChange(int progress) {
+        var unused =
+                ThreadUtils.postOnBackgroundThread(
+                        () -> {
+                            int groupId = BluetoothUtils.getGroupId(mCachedDevice);
+                            if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
+                                    && groupId
+                                            == BluetoothUtils.getPrimaryGroupIdForBroadcast(
+                                                    mContext.getContentResolver())) {
+                                // Set media stream volume for primary buds, audio manager will
+                                // update all buds volume in the audio sharing.
+                                setAudioManagerStreamVolume(progress);
+                            } else {
+                                // Set buds volume for other buds.
+                                setDeviceVolume(mCachedDevice.getDevice(), progress);
+                            }
+                        });
+    }
+
+    private void setDeviceVolume(@Nullable BluetoothDevice device, int progress) {
+        if (device == null) {
+            Log.d(TAG, "Skip set device volume, device is null");
+            return;
+        }
+        LocalBluetoothManager btManager = Utils.getLocalBtManager(mContext);
+        VolumeControlProfile vc =
+                btManager == null ? null : btManager.getProfileManager().getVolumeControlProfile();
+        if (vc != null) {
+            vc.setDeviceVolume(device, progress, /* isGroupOp= */ true);
+            mMetricsFeatureProvider.action(
+                    mContext,
+                    SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
+                    /* isPrimary= */ false);
+            Log.d(
+                    TAG,
+                    "set device volume, device = "
+                            + device.getAnonymizedAddress()
+                            + " volume = "
+                            + progress);
+        }
+    }
+
+    private void setAudioManagerStreamVolume(int progress) {
+        int seekbarRange =
+                AudioSharingDeviceVolumePreference.MAX_VOLUME
+                        - AudioSharingDeviceVolumePreference.MIN_VOLUME;
+        try {
+            AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+            int streamVolumeRange =
+                    audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
+                            - audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC);
+            int volume = Math.round((float) progress * streamVolumeRange / seekbarRange);
+            audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            mMetricsFeatureProvider.action(
+                    mContext,
+                    SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
+                    /* isPrimary= */ true);
+            Log.d(TAG, "set music stream volume, volume = " + progress);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Fail to setAudioManagerStreamVolumeForFallbackDevice, error = " + e);
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
index 219c37b..4f084a4 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java
@@ -114,7 +114,7 @@
         setUpMockProfiles();
         when(mCachedBluetoothDeviceManager.getCachedDevicesCopy())
                 .thenReturn(ImmutableList.of(mCachedDevice));
-        when(mCachedDevice.getConnectableProfiles())
+        when(mCachedDevice.getUiAccessibleProfiles())
                 .thenAnswer(invocation -> new ArrayList<>(mConnectableProfiles));
         when(mCachedDevice.getProfiles())
                 .thenAnswer(invocation -> ImmutableList.of(mConnectableProfiles));
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 f3f32ae..03f1303 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
@@ -303,7 +303,7 @@
 
     @Test
     public void onProfileConnectionStateChanged_notMediaDevice_doNothing() {
-        doReturn(ImmutableList.of()).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of()).when(mCachedDevice).getUiAccessibleProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice, BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.HID_DEVICE);
         verifyNoInteractions(mDialogHandler);
@@ -313,7 +313,7 @@
     public void onProfileConnectionStateChanged_leaDeviceDisconnected_closeOpeningDialogsForIt() {
         // Test when LEA device LE_AUDIO_BROADCAST_ASSISTANT disconnected.
         when(mDevice.isConnected()).thenReturn(true);
-        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice,
@@ -325,7 +325,7 @@
     @Test
     public void onProfileConnectionStateChanged_assistantProfileConnecting_doNothing() {
         // Test when LEA device LE_AUDIO_BROADCAST_ASSISTANT connecting
-        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice,
@@ -338,7 +338,7 @@
     public void onProfileConnectionStateChanged_otherProfileConnected_doNothing() {
         // Test when LEA device other profile connected
         when(mDevice.isConnected()).thenReturn(true);
-        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice, BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.A2DP);
@@ -349,7 +349,7 @@
     public void onProfileConnectionStateChanged_otherProfileConnecting_doNothing() {
         // Test when LEA device other profile connecting
         when(mDevice.isConnected()).thenReturn(true);
-        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice, BluetoothAdapter.STATE_CONNECTING, BluetoothProfile.A2DP);
@@ -360,7 +360,7 @@
     public void onProfileConnectionStateChanged_assistantProfileConnected_handle() {
         // Test when LEA device LE_AUDIO_BROADCAST_ASSISTANT connected
         when(mDevice.isConnected()).thenReturn(true);
-        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mLeAudioProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice,
@@ -374,7 +374,7 @@
             onProfileConnectionStateChanged_nonLeaDeviceDisconnected_closeOpeningDialogsForIt() {
         // Test when non-LEA device totally disconnected
         when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(false);
-        doReturn(ImmutableList.of(mA2dpProfile)).when(mCachedDevice).getConnectableProfiles();
+        doReturn(ImmutableList.of(mA2dpProfile)).when(mCachedDevice).getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mLeAudioProfile, mA2dpProfile)).when(mCachedDevice).getProfiles();
         when(mCachedDevice.isConnected()).thenReturn(false);
         mController.onProfileConnectionStateChanged(
@@ -390,7 +390,7 @@
                 .thenReturn(BluetoothAdapter.STATE_CONNECTED);
         doReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile))
                 .when(mCachedDevice)
-                .getConnectableProfiles();
+                .getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice, BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.A2DP);
@@ -405,7 +405,7 @@
                 .thenReturn(BluetoothAdapter.STATE_DISCONNECTED);
         doReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile))
                 .when(mCachedDevice)
-                .getConnectableProfiles();
+                .getUiAccessibleProfiles();
         doReturn(ImmutableList.of(mA2dpProfile, mHeadsetProfile)).when(mCachedDevice).getProfiles();
         mController.onProfileConnectionStateChanged(
                 mCachedDevice, BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.A2DP);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java
index 3c12946..95e51e9 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java
@@ -31,15 +31,11 @@
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
 
-import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
-import android.media.AudioManager;
 import android.os.Looper;
-import android.provider.Settings;
-import android.widget.SeekBar;
 
 import androidx.preference.Preference;
 import androidx.test.core.app.ApplicationProvider;
@@ -47,7 +43,6 @@
 import com.android.settings.bluetooth.BluetoothDevicePreference;
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
-import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -55,7 +50,6 @@
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-import com.android.settingslib.bluetooth.VolumeControlProfile;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -80,13 +74,7 @@
 @Config(shadows = {ShadowBluetoothUtils.class})
 public class AudioSharingDeviceVolumeControlUpdaterTest {
     private static final String TEST_DEVICE_NAME = "test";
-    private static final String TAG = "AudioSharingDeviceVolumeControlUpdater";
-    private static final String TEST_SETTINGS_KEY =
-            "bluetooth_le_broadcast_fallback_active_group_id";
-    private static final int TEST_DEVICE_GROUP_ID = 1;
-    private static final int TEST_VOLUME_VALUE = 255;
-    private static final int TEST_MAX_STREAM_VALUE = 10;
-    private static final int TEST_MIN_STREAM_VALUE = 0;
+    private static final String TAG = "AudioSharingVolUpdater";
 
     @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
@@ -98,39 +86,32 @@
     @Mock private LocalBluetoothProfileManager mLocalBtProfileManager;
     @Mock private LocalBluetoothLeBroadcast mBroadcast;
     @Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
-    @Mock private VolumeControlProfile mVolumeControl;
     @Mock private BluetoothLeBroadcastReceiveState mState;
-    @Mock private AudioManager mAudioManager;
 
     private Context mContext;
     private AudioSharingDeviceVolumeControlUpdater mDeviceUpdater;
     private Collection<CachedBluetoothDevice> mCachedDevices;
-    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setUp() {
-        mContext = spy(ApplicationProvider.getApplicationContext());
+        mContext = ApplicationProvider.getApplicationContext();
         ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
         mLocalBtManager = Utils.getLocalBtManager(mContext);
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
         when(mLocalBtManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
         when(mLocalBtManager.getProfileManager()).thenReturn(mLocalBtProfileManager);
         when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
         when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
-        when(mLocalBtProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl);
         List<Long> bisSyncState = new ArrayList<>();
         bisSyncState.add(1L);
         when(mState.getBisSyncState()).thenReturn(bisSyncState);
         doReturn(TEST_DEVICE_NAME).when(mCachedBluetoothDevice).getName();
         doReturn(mBluetoothDevice).when(mCachedBluetoothDevice).getDevice();
         doReturn(ImmutableSet.of()).when(mCachedBluetoothDevice).getMemberDevice();
-        doReturn(TEST_DEVICE_GROUP_ID).when(mCachedBluetoothDevice).getGroupId();
         mCachedDevices = new ArrayList<>();
         mCachedDevices.add(mCachedBluetoothDevice);
         when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
         doNothing().when(mDevicePreferenceCallback).onDeviceAdded(any(Preference.class));
         doNothing().when(mDevicePreferenceCallback).onDeviceRemoved(any(Preference.class));
-        when(mContext.getSystemService(AudioManager.class)).thenReturn(mAudioManager);
         mDeviceUpdater =
                 spy(
                         new AudioSharingDeviceVolumeControlUpdater(
@@ -251,76 +232,6 @@
     }
 
     @Test
-    public void addPreference_notFallbackDevice_setDeviceVolume() {
-        ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class);
-        setupPreferenceMapWithDevice();
-
-        verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
-        assertThat(captor.getValue() instanceof AudioSharingDeviceVolumePreference).isTrue();
-        AudioSharingDeviceVolumePreference preference =
-                (AudioSharingDeviceVolumePreference) captor.getValue();
-
-        SeekBar seekBar = mock(SeekBar.class);
-        when(seekBar.getProgress()).thenReturn(TEST_VOLUME_VALUE);
-        preference.onStopTrackingTouch(seekBar);
-
-        verify(mVolumeControl)
-                .setDeviceVolume(mBluetoothDevice, TEST_VOLUME_VALUE, /* isGroupOp= */ true);
-        verifyNoInteractions(mAudioManager);
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        mContext,
-                        SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
-                        /* isPrimary= */ false);
-    }
-
-    @Test
-    public void addPreference_fallbackDevice_setStreamVolume() {
-        ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class);
-        setupPreferenceMapWithDevice();
-
-        verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
-        assertThat(captor.getValue() instanceof AudioSharingDeviceVolumePreference).isTrue();
-        AudioSharingDeviceVolumePreference preference =
-                (AudioSharingDeviceVolumePreference) captor.getValue();
-
-        Settings.Secure.putInt(
-                mContext.getContentResolver(), TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID);
-        when(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
-                .thenReturn(TEST_MAX_STREAM_VALUE);
-        when(mAudioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC))
-                .thenReturn(TEST_MIN_STREAM_VALUE);
-        SeekBar seekBar = mock(SeekBar.class);
-        when(seekBar.getProgress()).thenReturn(TEST_VOLUME_VALUE);
-        preference.onStopTrackingTouch(seekBar);
-
-        verifyNoInteractions(mVolumeControl);
-        verify(mAudioManager)
-                .setStreamVolume(AudioManager.STREAM_MUSIC, TEST_MAX_STREAM_VALUE, /* flags= */ 0);
-        verify(mFeatureFactory.metricsFeatureProvider)
-                .action(
-                        mContext,
-                        SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
-                        /* isPrimary= */ true);
-    }
-
-    @Test
-    public void testOnSeekBarChangeListener_doNothing() {
-        ArgumentCaptor<Preference> captor = ArgumentCaptor.forClass(Preference.class);
-        setupPreferenceMapWithDevice();
-
-        verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
-        assertThat(captor.getValue() instanceof AudioSharingDeviceVolumePreference).isTrue();
-        AudioSharingDeviceVolumePreference preference =
-                (AudioSharingDeviceVolumePreference) captor.getValue();
-        SeekBar seekBar = mock(SeekBar.class);
-        preference.onProgressChanged(seekBar, TEST_VOLUME_VALUE, /* fromUser= */ false);
-
-        verifyNoInteractions(mAudioManager);
-        verifyNoInteractions(mVolumeControl);
-    }
-
-    @Test
     public void getLogTag_returnsCorrectTag() {
         assertThat(mDeviceUpdater.getLogTag()).isEqualTo(TAG);
     }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreferenceTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreferenceTest.java
index 8ceb0eb..5ff143f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumePreferenceTest.java
@@ -18,11 +18,32 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.settings.SettingsEnums;
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
+import android.media.AudioManager;
+import android.provider.Settings;
+import android.widget.SeekBar;
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.bluetooth.VolumeControlProfile;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -32,18 +53,45 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothUtils.class})
 public class AudioSharingDeviceVolumePreferenceTest {
+    private static final int TEST_DEVICE_GROUP_ID = 1;
+    private static final int TEST_VOLUME_VALUE = 255;
+    private static final int TEST_MAX_STREAM_VALUE = 10;
+    private static final int TEST_MIN_STREAM_VALUE = 0;
+
     @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
+    @Mock private LocalBluetoothManager mLocalBtManager;
+    @Mock private LocalBluetoothProfileManager mLocalBtProfileManager;
+    @Mock private VolumeControlProfile mVolumeControl;
     @Mock private CachedBluetoothDevice mCachedDevice;
+    @Mock private BluetoothDevice mDevice;
+    @Mock private AudioManager mAudioManager;
+    @Mock private SeekBar mSeekBar;
     private Context mContext;
     private AudioSharingDeviceVolumePreference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setup() {
-        mContext = ApplicationProvider.getApplicationContext();
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
+        mLocalBtManager = Utils.getLocalBtManager(mContext);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
+        when(mLocalBtManager.getProfileManager()).thenReturn(mLocalBtProfileManager);
+        when(mLocalBtProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl);
+        when(mContext.getSystemService(AudioManager.class)).thenReturn(mAudioManager);
+        when(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
+                .thenReturn(TEST_MAX_STREAM_VALUE);
+        when(mAudioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC))
+                .thenReturn(TEST_MIN_STREAM_VALUE);
+        when(mCachedDevice.getDevice()).thenReturn(mDevice);
+        when(mCachedDevice.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID);
+        when(mSeekBar.getProgress()).thenReturn(TEST_VOLUME_VALUE);
         mPreference = new AudioSharingDeviceVolumePreference(mContext, mCachedDevice);
     }
 
@@ -58,4 +106,128 @@
         assertThat(mPreference.getMax()).isEqualTo(AudioSharingDeviceVolumePreference.MAX_VOLUME);
         assertThat(mPreference.getMin()).isEqualTo(AudioSharingDeviceVolumePreference.MIN_VOLUME);
     }
+
+    @Test
+    public void onStopTrackingTouch_notFallbackDevice_setDeviceVolume() {
+        mPreference.onStopTrackingTouch(mSeekBar);
+
+        verify(mVolumeControl).setDeviceVolume(mDevice, TEST_VOLUME_VALUE, /* isGroupOp= */ true);
+        verifyNoInteractions(mAudioManager);
+        verify(mFeatureFactory.metricsFeatureProvider)
+                .action(
+                        mContext,
+                        SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
+                        /* isPrimary= */ false);
+    }
+
+    @Test
+    public void onProgressChanged_notFallbackDevice_fromUserNotInTouch_setDeviceVolume() {
+        mPreference.onProgressChanged(mSeekBar, TEST_VOLUME_VALUE, /* fromUser= */ true);
+
+        verify(mVolumeControl).setDeviceVolume(mDevice, TEST_VOLUME_VALUE, /* isGroupOp= */ true);
+        verifyNoInteractions(mAudioManager);
+        verify(mFeatureFactory.metricsFeatureProvider)
+                .action(
+                        mContext,
+                        SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
+                        /* isPrimary= */ false);
+    }
+
+    @Test
+    public void onProgressChanged_notFallbackDevice_fromUserInTouch_doNothing() {
+        mPreference.onStartTrackingTouch(mSeekBar);
+        mPreference.onProgressChanged(mSeekBar, TEST_VOLUME_VALUE, /* fromUser= */ true);
+
+        verifyNoInteractions(mVolumeControl);
+        verifyNoInteractions(mAudioManager);
+        verify(mFeatureFactory.metricsFeatureProvider, never())
+                .action(
+                        any(Context.class),
+                        eq(SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME),
+                        anyBoolean());
+    }
+
+    @Test
+    public void onProgressChanged_notFallbackDevice_notFromUserNotInTouch_doNothing() {
+        mPreference.onProgressChanged(mSeekBar, TEST_VOLUME_VALUE, /* fromUser= */ false);
+
+        verifyNoInteractions(mVolumeControl);
+        verifyNoInteractions(mAudioManager);
+        verify(mFeatureFactory.metricsFeatureProvider, never())
+                .action(
+                        any(Context.class),
+                        eq(SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME),
+                        anyBoolean());
+    }
+
+    @Test
+    public void onStopTrackingTouch_fallbackDevice_setDeviceVolume() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+                TEST_DEVICE_GROUP_ID);
+        mPreference.onStopTrackingTouch(mSeekBar);
+
+        verifyNoInteractions(mVolumeControl);
+        verify(mAudioManager)
+                .setStreamVolume(AudioManager.STREAM_MUSIC, TEST_MAX_STREAM_VALUE, /* flags= */ 0);
+        verify(mFeatureFactory.metricsFeatureProvider)
+                .action(
+                        mContext,
+                        SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
+                        /* isPrimary= */ true);
+    }
+
+    @Test
+    public void onProgressChanged_fallbackDevice_fromUserNotInTouch_setDeviceVolume() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+                TEST_DEVICE_GROUP_ID);
+        mPreference.onProgressChanged(mSeekBar, TEST_VOLUME_VALUE, /* fromUser= */ true);
+
+        verifyNoInteractions(mVolumeControl);
+        verify(mAudioManager)
+                .setStreamVolume(AudioManager.STREAM_MUSIC, TEST_MAX_STREAM_VALUE, /* flags= */ 0);
+        verify(mFeatureFactory.metricsFeatureProvider)
+                .action(
+                        mContext,
+                        SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME,
+                        /* isPrimary= */ true);
+    }
+
+    @Test
+    public void onProgressChanged_fallbackDevice_fromUserInTouch_doNothing() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+                TEST_DEVICE_GROUP_ID);
+        mPreference.onStartTrackingTouch(mSeekBar);
+        mPreference.onProgressChanged(mSeekBar, TEST_VOLUME_VALUE, /* fromUser= */ true);
+
+        verifyNoInteractions(mVolumeControl);
+        verifyNoInteractions(mAudioManager);
+        verify(mFeatureFactory.metricsFeatureProvider, never())
+                .action(
+                        any(Context.class),
+                        eq(SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME),
+                        anyBoolean());
+    }
+
+    @Test
+    public void onProgressChanged_fallbackDevice_notFromUserNotInTouch_doNothing() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+                TEST_DEVICE_GROUP_ID);
+        mPreference.onProgressChanged(mSeekBar, TEST_VOLUME_VALUE, /* fromUser= */ false);
+
+        verifyNoInteractions(mVolumeControl);
+        verifyNoInteractions(mAudioManager);
+        verify(mFeatureFactory.metricsFeatureProvider, never())
+                .action(
+                        any(Context.class),
+                        eq(SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_MEDIA_DEVICE_VOLUME),
+                        anyBoolean());
+    }
 }