Merge "[Audiosharing] Impl audio sharing feature provider in Settings" into main
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index 23ba4f6..8250f70 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -23,7 +23,7 @@
 import androidx.preference.Preference;
 
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 
@@ -72,6 +72,32 @@
         if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
             Log.d(TAG, "isFilterMatched() current audio profile : " + currentAudioProfile);
 
+            // If device is LE Audio, it is compatible with HFP and A2DP.
+            // It would show in Available Devices group if the audio sharing flag is disabled or
+            // the device is not in the audio sharing session.
+            if (cachedDevice.isConnectedLeAudioDevice()) {
+                boolean isAudioSharingFilterMatched =
+                        FeatureFactory.getFeatureFactory()
+                                .getAudioSharingFeatureProvider()
+                                .isAudioSharingFilterMatched(cachedDevice, mLocalManager);
+                if (!isAudioSharingFilterMatched) {
+                    Log.d(
+                            TAG,
+                            "isFilterMatched() device : "
+                                    + cachedDevice.getName()
+                                    + ", the LE Audio profile is connected and not in sharing "
+                                    + "if broadcast enabled.");
+                    return true;
+                } else {
+                    Log.d(
+                            TAG,
+                            "Filter out device : "
+                                    + cachedDevice.getName()
+                                    + ", it is in audio sharing.");
+                    return false;
+                }
+            }
+
             // If device is Hearing Aid, it is compatible with HFP and A2DP.
             // It would show in Available Devices group.
             if (cachedDevice.isConnectedAshaHearingAidDevice()) {
@@ -82,20 +108,7 @@
                                 + ", the Hearing Aid profile is connected.");
                 return true;
             }
-            // If device is LE Audio, it is compatible with HFP and A2DP.
-            // It would show in Available Devices group if the audio sharing flag is disabled or
-            // the device is not in the audio sharing session.
-            if (cachedDevice.isConnectedLeAudioDevice()) {
-                if (!AudioSharingUtils.isFeatureEnabled()
-                        || !AudioSharingUtils.hasBroadcastSource(cachedDevice, mLocalManager)) {
-                    Log.d(
-                            TAG,
-                            "isFilterMatched() device : "
-                                    + cachedDevice.getName()
-                                    + ", the LE Audio profile is connected and not in sharing.");
-                    return true;
-                }
-            }
+
             // According to the current audio profile type,
             // this page will show the bluetooth device that have corresponding profile.
             // For example:
@@ -125,13 +138,9 @@
         mMetricsFeatureProvider.logClickedPreference(preference, mMetricsCategory);
         final CachedBluetoothDevice device =
                 ((BluetoothDevicePreference) preference).getBluetoothDevice();
-        if (AudioSharingUtils.isFeatureEnabled()
-                && AudioSharingUtils.isBroadcasting(mLocalBtManager)) {
-            if (DBG) {
-                Log.d(TAG, "onPreferenceClick stop broadcasting.");
-            }
-            AudioSharingUtils.stopBroadcasting(mLocalBtManager);
-        }
+        FeatureFactory.getFeatureFactory()
+                .getAudioSharingFeatureProvider()
+                .handleMediaDeviceOnClick(mLocalManager);
         return device.setActive();
     }
 
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index 27001d6..2798be4 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -22,12 +22,13 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
-import com.android.settings.connecteddevice.audiosharing.AudioSharingDevicePreferenceController;
 import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settings.core.SettingsUIDeviceConfig;
 import com.android.settings.dashboard.DashboardFragment;
@@ -36,8 +37,12 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.slices.SlicePreferenceController;
 import com.android.settingslib.bluetooth.HearingAidStatsLogUtils;
+import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class ConnectedDeviceDashboardFragment extends DashboardFragment {
 
@@ -87,9 +92,6 @@
                             + ", action : "
                             + action);
         }
-        if (AudioSharingUtils.isFeatureEnabled()) {
-            use(AudioSharingDevicePreferenceController.class).init(this);
-        }
         use(AvailableMediaDeviceGroupController.class).init(this);
         use(ConnectedDeviceGroupController.class).init(this);
         use(PreviouslyConnectedDevicePreferenceController.class).init(this);
@@ -112,6 +114,29 @@
         }
     }
 
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context, /* fragment= */ this, getSettingsLifecycle());
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(
+            Context context,
+            @Nullable ConnectedDeviceDashboardFragment fragment,
+            @Nullable Lifecycle lifecycle) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+        if (AudioSharingUtils.isFeatureEnabled()) {
+            AbstractPreferenceController audioSharingController =
+                    FeatureFactory.getFeatureFactory()
+                            .getAudioSharingFeatureProvider()
+                            .createAudioSharingDevicePreferenceController(
+                                    context, fragment, lifecycle);
+            if (audioSharingController != null) {
+                controllers.add(audioSharingController);
+            }
+        }
+        return controllers;
+    }
+
     @VisibleForTesting
     boolean isAlwaysDiscoverable(String callingAppPackageName, String action) {
         return TextUtils.equals(SLICE_ACTION, action)
@@ -122,5 +147,12 @@
 
     /** For Search. */
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.connected_devices);
+            new BaseSearchIndexProvider(R.xml.connected_devices) {
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(
+                            context, /* fragment= */ null, /* lifecycle= */ null);
+                }
+            };
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
new file mode 100644
index 0000000..c71a368
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 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.connecteddevice.audiosharing;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/** Feature provider for the audio sharing related features, */
+public interface AudioSharingFeatureProvider {
+
+    /** Create audio sharing device preference controller. */
+    @Nullable
+    AbstractPreferenceController createAudioSharingDevicePreferenceController(
+            @NonNull Context context,
+            @Nullable DashboardFragment fragment,
+            @Nullable Lifecycle lifecycle);
+
+    /**
+     * Check if the device match the audio sharing filter.
+     *
+     * <p>The filter is used to filter device in "Media devices" section.
+     */
+    boolean isAudioSharingFilterMatched(
+            @NonNull CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager);
+
+    /** Handle preference onClick in "Media devices" section. */
+    void handleMediaDeviceOnClick(LocalBluetoothManager localBtManager);
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
new file mode 100644
index 0000000..05a6a63
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 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.connecteddevice.audiosharing;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class AudioSharingFeatureProviderImpl implements AudioSharingFeatureProvider {
+
+    @Nullable
+    @Override
+    public AbstractPreferenceController createAudioSharingDevicePreferenceController(
+            @NonNull Context context,
+            @Nullable DashboardFragment fragment,
+            @Nullable Lifecycle lifecycle) {
+        return null;
+    }
+
+    @Override
+    public boolean isAudioSharingFilterMatched(
+            @NonNull CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager) {
+        return false;
+    }
+
+    @Override
+    public void handleMediaDeviceOnClick(LocalBluetoothManager localBtManager) {}
+}
diff --git a/src/com/android/settings/overlay/FeatureFactory.kt b/src/com/android/settings/overlay/FeatureFactory.kt
index 37507a8..2c4a295 100644
--- a/src/com/android/settings/overlay/FeatureFactory.kt
+++ b/src/com/android/settings/overlay/FeatureFactory.kt
@@ -24,6 +24,7 @@
 import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider
 import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider
 import com.android.settings.bluetooth.BluetoothFeatureProvider
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProvider
 import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
 import com.android.settings.connecteddevice.stylus.StylusFeatureProvider
 import com.android.settings.dashboard.DashboardFeatureProvider
@@ -182,6 +183,11 @@
      */
     abstract val displayFeatureProvider: DisplayFeatureProvider
 
+    /**
+     * Gets implementation for audio sharing related feature.
+     */
+    abstract val audioSharingFeatureProvider: AudioSharingFeatureProvider
+
     companion object {
         private var _factory: FeatureFactory? = null
 
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.kt b/src/com/android/settings/overlay/FeatureFactoryImpl.kt
index e0313b7..e1519b3 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.kt
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.kt
@@ -34,6 +34,8 @@
 import com.android.settings.biometrics2.factory.BiometricsRepositoryProviderImpl
 import com.android.settings.bluetooth.BluetoothFeatureProvider
 import com.android.settings.bluetooth.BluetoothFeatureProviderImpl
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProvider
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProviderImpl
 import com.android.settings.connecteddevice.dock.DockUpdaterFeatureProviderImpl
 import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
 import com.android.settings.connecteddevice.fastpair.FastPairFeatureProviderImpl
@@ -192,7 +194,12 @@
     override val privateSpaceLoginFeatureProvider: PrivateSpaceLoginFeatureProvider by lazy {
         PrivateSpaceLoginFeatureProviderImpl()
     }
+
     override val displayFeatureProvider: DisplayFeatureProvider by lazy {
         DisplayFeatureProviderImpl()
     }
+
+    override val audioSharingFeatureProvider: AudioSharingFeatureProvider by lazy {
+        AudioSharingFeatureProviderImpl()
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
index dceadeb..5a7e247 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
@@ -16,7 +16,6 @@
 package com.android.settings.bluetooth;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -25,36 +24,26 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothStatusCodes;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.util.Pair;
 
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProvider;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.flags.Flags;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowAudioManager;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
-import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
-import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -75,9 +64,6 @@
             ShadowBluetoothUtils.class
         })
 public class AvailableMediaBluetoothDeviceUpdaterTest {
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
 
     @Mock private DashboardFragment mDashboardFragment;
@@ -86,11 +72,7 @@
     @Mock private BluetoothDevice mBluetoothDevice;
     @Mock private Drawable mDrawable;
     @Mock private LocalBluetoothManager mLocalBtManager;
-    @Mock private LocalBluetoothProfileManager mLocalBtProfileManager;
     @Mock private CachedBluetoothDeviceManager mCachedDeviceManager;
-    @Mock private LocalBluetoothLeBroadcast mBroadcast;
-    @Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
-    @Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
 
     private Context mContext;
     private AvailableMediaBluetoothDeviceUpdater mBluetoothDeviceUpdater;
@@ -98,12 +80,14 @@
     private AudioManager mAudioManager;
     private BluetoothDevicePreference mPreference;
     private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+    private AudioSharingFeatureProvider mFeatureProvider;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
         mContext = RuntimeEnvironment.application;
+        mFeatureProvider = FakeFeatureFactory.setupForTest().getAudioSharingFeatureProvider();
         mAudioManager = mContext.getSystemService(AudioManager.class);
         ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
         mLocalBtManager = Utils.getLocalBtManager(mContext);
@@ -267,13 +251,15 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void onProfileConnectionStateChanged_leAudioDeviceConnected_notInCall_addsPreference() {
-        setUpBroadcast(/* isSupported= */ false, /* isBroadcasting= */ false);
+    public void
+            onProfileConnectionStateChanged_leaDeviceConnected_notInCallNoSharing_addsPreference() {
         mAudioManager.setMode(AudioManager.MODE_NORMAL);
         when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
                 .thenReturn(true);
         when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+        when(mFeatureProvider.isAudioSharingFilterMatched(
+                        any(CachedBluetoothDevice.class), any(LocalBluetoothManager.class)))
+                .thenReturn(false);
 
         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
                 mCachedBluetoothDevice,
@@ -284,13 +270,15 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void onProfileConnectionStateChanged_leAudioDeviceConnected_inCall_addsPreference() {
-        setUpBroadcast(/* isSupported= */ false, /* isBroadcasting= */ false);
+    public void
+            onProfileConnectionStateChanged_leaDeviceConnected_inCallNoSharing_addsPreference() {
         mAudioManager.setMode(AudioManager.MODE_IN_CALL);
         when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
                 .thenReturn(true);
         when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+        when(mFeatureProvider.isAudioSharingFilterMatched(
+                        any(CachedBluetoothDevice.class), any(LocalBluetoothManager.class)))
+                .thenReturn(false);
 
         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
                 mCachedBluetoothDevice,
@@ -301,50 +289,16 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void
-            onProfileConnectionStateChanged_leaDeviceConnected_notInCall_notInBroadcast_addsPref() {
-        setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ false);
+            onProfileConnectionStateChanged_leaDeviceConnected_notInCallInSharing_removesPref() {
         mAudioManager.setMode(AudioManager.MODE_NORMAL);
         when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
                 .thenReturn(true);
         when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
-
-        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
-                mCachedBluetoothDevice,
-                BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.LE_AUDIO);
-
-        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void
-            onProfileConnectionStateChanged_leaDeviceConnected_inCall_notInBroadcast_addsPref() {
-        setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ false);
-        mAudioManager.setMode(AudioManager.MODE_IN_CALL);
-        when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
+        when(mCachedBluetoothDevice.isConnectedA2dpDevice()).thenReturn(true);
+        when(mFeatureProvider.isAudioSharingFilterMatched(
+                        any(CachedBluetoothDevice.class), any(LocalBluetoothManager.class)))
                 .thenReturn(true);
-        when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
-
-        mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
-                mCachedBluetoothDevice,
-                BluetoothProfile.STATE_CONNECTED,
-                BluetoothProfile.LE_AUDIO);
-
-        verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void
-            onProfileConnectionStateChanged_leaDeviceConnected_notInCall_inBroadcast_removesPref() {
-        setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ true);
-        mAudioManager.setMode(AudioManager.MODE_NORMAL);
-        when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
-                .thenReturn(true);
-        when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
 
         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
                 mCachedBluetoothDevice,
@@ -355,14 +309,15 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void
-            onProfileConnectionStateChanged_leaDeviceConnected_inCall_inBroadcast_removesPref() {
-        setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ true);
-        mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+    public void onProfileConnectionStateChanged_leaDeviceConnected_inCallInSharing_removesPref() {
+        mAudioManager.setMode(AudioManager.MODE_NORMAL);
         when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
                 .thenReturn(true);
         when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
+        when(mCachedBluetoothDevice.isConnectedHfpDevice()).thenReturn(true);
+        when(mFeatureProvider.isAudioSharingFilterMatched(
+                        any(CachedBluetoothDevice.class), any(LocalBluetoothManager.class)))
+                .thenReturn(true);
 
         mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
                 mCachedBluetoothDevice,
@@ -414,56 +369,9 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onClick_Preference_setActive() {
-        setUpBroadcast(/* isSupported= */ false, /* isBroadcasting= */ false);
         mBluetoothDeviceUpdater.onPreferenceClick(mPreference);
 
         verify(mCachedBluetoothDevice).setActive();
     }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void onClick_Preference_isNotBroadcasting_setActive() {
-        setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ false);
-        mBluetoothDeviceUpdater.onPreferenceClick(mPreference);
-
-        verify(mCachedBluetoothDevice).setActive();
-    }
-
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
-    public void onClick_Preference_isBroadcasting_stopBroadcastingAndSetActive() {
-        setUpBroadcast(/* isSupported= */ true, /* isBroadcasting= */ true);
-        doNothing().when(mBroadcast).stopBroadcast(anyInt());
-        mBluetoothDeviceUpdater.onPreferenceClick(mPreference);
-
-        verify(mBroadcast).stopBroadcast(anyInt());
-        verify(mCachedBluetoothDevice).setActive();
-    }
-
-    private void setUpBroadcast(boolean isSupported, boolean isBroadcasting) {
-        if (isSupported) {
-            mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
-                    BluetoothStatusCodes.FEATURE_SUPPORTED);
-            mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
-                    BluetoothStatusCodes.FEATURE_SUPPORTED);
-            when(mLocalBtManager.getProfileManager()).thenReturn(mLocalBtProfileManager);
-            when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
-            when(mBroadcast.isEnabled(null)).thenReturn(isBroadcasting);
-            when(mLocalBtProfileManager.getLeAudioBroadcastAssistantProfile())
-                    .thenReturn(mAssistant);
-            if (isBroadcasting) {
-                when(mAssistant.getAllSources(any()))
-                        .thenReturn(ImmutableList.of(mBroadcastReceiveState));
-            } else {
-                when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
-            }
-        } else {
-            mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
-                    BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
-            mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
-                    BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
-        }
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java
new file mode 100644
index 0000000..0edbc77
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImplTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2024 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.connecteddevice.audiosharing;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class AudioSharingFeatureProviderImplTest {
+    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock private CachedBluetoothDevice mCachedDevice;
+    @Mock private LocalBluetoothManager mLocalBtManager;
+    @Mock private DashboardFragment mFragment;
+    private Context mContext;
+    private AudioSharingFeatureProviderImpl mFeatureProvider;
+
+    @Before
+    public void setUp() {
+        mContext = ApplicationProvider.getApplicationContext();
+        mFeatureProvider = new AudioSharingFeatureProviderImpl();
+    }
+
+    @Test
+    public void createAudioSharingDevicePreferenceController_returnsNull() {
+        assertThat(
+                        mFeatureProvider.createAudioSharingDevicePreferenceController(
+                                mContext, mFragment, /* lifecycle= */ null))
+                .isNull();
+    }
+
+    @Test
+    public void isAudioSharingFilterMatched_returnsFalse() {
+        assertThat(mFeatureProvider.isAudioSharingFilterMatched(mCachedDevice, mLocalBtManager))
+                .isFalse();
+    }
+}
diff --git a/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java
index a11b226..f49cc68 100644
--- a/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java
@@ -27,6 +27,7 @@
 import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider;
 import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProvider;
 import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
 import com.android.settings.connecteddevice.stylus.StylusFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
@@ -103,6 +104,7 @@
     public FastPairFeatureProvider mFastPairFeatureProvider;
     public PrivateSpaceLoginFeatureProvider mPrivateSpaceLoginFeatureProvider;
     public DisplayFeatureProvider mDisplayFeatureProvider;
+    public AudioSharingFeatureProvider mAudioSharingFeatureProvider;
 
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
@@ -152,6 +154,7 @@
         mFastPairFeatureProvider = mock(FastPairFeatureProvider.class);
         mPrivateSpaceLoginFeatureProvider =  mock(PrivateSpaceLoginFeatureProvider.class);
         mDisplayFeatureProvider = mock(DisplayFeatureProvider.class);
+        mAudioSharingFeatureProvider = mock(AudioSharingFeatureProvider.class);
     }
 
     @Override
@@ -339,5 +342,10 @@
     public DisplayFeatureProvider getDisplayFeatureProvider() {
         return mDisplayFeatureProvider;
     }
+
+    @Override
+    public AudioSharingFeatureProvider getAudioSharingFeatureProvider() {
+        return mAudioSharingFeatureProvider;
+    }
 }
 
diff --git a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
index 4048c24..606db8e 100644
--- a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
+++ b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
@@ -25,6 +25,7 @@
 import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider
 import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider
 import com.android.settings.bluetooth.BluetoothFeatureProvider
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProvider
 import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider
 import com.android.settings.connecteddevice.stylus.StylusFeatureProvider
 import com.android.settings.dashboard.DashboardFeatureProvider
@@ -149,4 +150,6 @@
         get() = TODO("Not yet implemented")
     override val displayFeatureProvider: DisplayFeatureProvider
         get() = TODO("Not yet implemented")
+    override val audioSharingFeatureProvider: AudioSharingFeatureProvider
+        get() = TODO("Not yet implemented")
 }
diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
index 9e7948c..4f17a3a 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -27,6 +27,7 @@
 import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider;
 import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
 import com.android.settings.bluetooth.BluetoothFeatureProvider;
+import com.android.settings.connecteddevice.audiosharing.AudioSharingFeatureProvider;
 import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
 import com.android.settings.connecteddevice.stylus.StylusFeatureProvider;
 import com.android.settings.dashboard.DashboardFeatureProvider;
@@ -102,6 +103,7 @@
     public FastPairFeatureProvider mFastPairFeatureProvider;
     public PrivateSpaceLoginFeatureProvider mPrivateSpaceLoginFeatureProvider;
     public DisplayFeatureProvider mDisplayFeatureProvider;
+    public AudioSharingFeatureProvider mAudioSharingFeatureProvider;
 
     /** Call this in {@code @Before} method of the test class to use fake factory. */
     public static FakeFeatureFactory setupForTest() {
@@ -153,6 +155,7 @@
         mFastPairFeatureProvider = mock(FastPairFeatureProvider.class);
         mPrivateSpaceLoginFeatureProvider = mock(PrivateSpaceLoginFeatureProvider.class);
         mDisplayFeatureProvider = mock(DisplayFeatureProvider.class);
+        mAudioSharingFeatureProvider = mock(AudioSharingFeatureProvider.class);
     }
 
     @Override
@@ -340,4 +343,9 @@
     public DisplayFeatureProvider getDisplayFeatureProvider() {
         return mDisplayFeatureProvider;
     }
+
+    @Override
+    public AudioSharingFeatureProvider getAudioSharingFeatureProvider() {
+        return mAudioSharingFeatureProvider;
+    }
 }