[Audiosharing] Use setBroadcastToUnicastFallbackGroup to set primary

Flag: com.android.settingslib.flags.adopt_primary_group_management_api
Test: atest
Bug: 381946931
Change-Id: Ib06dd2e202b07b9cdb25b1a671ee4d57246415ba
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
index 3130a0c..25180d8 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.connecteddevice.audiosharing;
 
+import static com.android.settingslib.Utils.isAudioModeOngoingCall;
+
 import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothCsipSetCoordinator;
@@ -48,6 +50,7 @@
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LeAudioProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -91,6 +94,7 @@
     Map<Integer, List<BluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
     private List<AudioSharingDeviceItem> mDeviceItemsInSharingSession = new ArrayList<>();
     private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
+    private AtomicBoolean mIsAudioModeOngoingCall = new AtomicBoolean(false);
 
     @VisibleForTesting
     final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
@@ -202,28 +206,15 @@
                                     mDeviceItemsInSharingSession,
                                     pair == null ? -1 : pair.first,
                                     (AudioSharingDeviceItem item) -> {
-                                        int currentGroupId =
+                                        int currentCallAudioGroupId =
                                                 BluetoothUtils.getPrimaryGroupIdForBroadcast(
                                                         mContext.getContentResolver());
                                         int clickedGroupId = item.getGroupId();
-                                        if (clickedGroupId == currentGroupId) {
+                                        if (clickedGroupId == currentCallAudioGroupId) {
                                             Log.d(TAG, "Skip set call audio device: unchanged");
                                             return;
                                         }
-                                        List<BluetoothDevice> devices =
-                                                mGroupedConnectedDevices.getOrDefault(
-                                                        clickedGroupId, ImmutableList.of());
-                                        CachedBluetoothDevice lead =
-                                                AudioSharingUtils.getLeadDevice(
-                                                        mCacheManager, devices);
-                                        if (lead != null) {
-                                            String addr = lead.getDevice().getAnonymizedAddress();
-                                            Log.d(TAG, "Set call audio device: " + addr);
-                                            AudioSharingUtils.setPrimary(mContext, lead);
-                                            logCallAudioDeviceChange(currentGroupId, lead);
-                                        } else {
-                                            Log.d(TAG, "Skip set call audio device: no lead");
-                                        }
+                                        setCallAudioGroup(clickedGroupId);
                                     });
                         }
                         return true;
@@ -269,6 +260,11 @@
         }
     }
 
+    @Override
+    public void onAudioModeChanged() {
+        mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext));
+    }
+
     /**
      * Initialize the controller.
      *
@@ -311,6 +307,7 @@
                     false,
                     mSettingsObserver);
             mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
+            mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext));
             mCallbacksRegistered.set(true);
         }
     }
@@ -333,6 +330,32 @@
         }
     }
 
+    private void setCallAudioGroup(int groupId) {
+        List<BluetoothDevice> devices =
+                mGroupedConnectedDevices.getOrDefault(
+                        groupId, ImmutableList.of());
+        CachedBluetoothDevice lead =
+                AudioSharingUtils.getLeadDevice(
+                        mCacheManager, devices);
+        if (lead != null) {
+            String addr = lead.getDevice().getAnonymizedAddress();
+            Log.d(TAG, "Set call audio device: " + addr);
+            if (Flags.adoptPrimaryGroupManagementApi() && !mIsAudioModeOngoingCall.get()) {
+                LeAudioProfile leaProfile = mBtManager == null ? null
+                        : mBtManager.getProfileManager().getLeAudioProfile();
+                if (leaProfile != null) {
+                    leaProfile.setBroadcastToUnicastFallbackGroup(groupId);
+                }
+            } else {
+                lead.setActive();
+            }
+            AudioSharingUtils.setUserPreferredPrimary(mContext, lead);
+            logCallAudioDeviceChange(groupId, lead);
+        } else {
+            Log.d(TAG, "Skip set call audio device: no lead");
+        }
+    }
+
     /**
      * Update the preference summary: current headset for call audio.
      *
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
index c286ed6..ffbb13e 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java
@@ -389,7 +389,8 @@
             Log.d(TAG, "onDeviceClick, set active in call mode");
             CachedBluetoothDevice cachedDevice =
                     ((BluetoothDevicePreference) preference).getBluetoothDevice();
-            AudioSharingUtils.setPrimary(mContext, cachedDevice);
+            cachedDevice.setActive();
+            AudioSharingUtils.setUserPreferredPrimary(mContext, cachedDevice);
         }
         mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUDIO_SHARING_DEVICE_CLICK,
                 isCallMode);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
index 0c34487..2a1f4da 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
@@ -192,7 +192,8 @@
                     // If this method is called with user triggered, e.g. manual click on the
                     // "Connected devices" page, we need call setActive for the device, since user
                     // intend to switch active device for the call.
-                    AudioSharingUtils.setPrimary(mContext, cachedDevice);
+                    cachedDevice.setActive();
+                    AudioSharingUtils.setUserPreferredPrimary(mContext, cachedDevice);
                 }
                 return;
             }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index 5a15b6a..7824b26 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -346,11 +346,10 @@
         return vc != null && vc.isProfileReady();
     }
 
-    /** Set {@link CachedBluetoothDevice} as primary device for call audio */
-    public static void setPrimary(
+    /** Set {@link CachedBluetoothDevice} as user preferred primary device for call audio */
+    public static void setUserPreferredPrimary(
             @NonNull Context context, @Nullable CachedBluetoothDevice cachedDevice) {
         if (cachedDevice == null) return;
-        cachedDevice.setActive();
         if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context)) {
             int groupId = BluetoothUtils.getGroupId(cachedDevice);
             // TODO: use real key name in SettingsProvider
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
index 3075573..a2ac0cc 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -67,6 +68,7 @@
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LeAudioProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -77,7 +79,6 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 
 import org.junit.After;
 import org.junit.Before;
@@ -89,8 +90,10 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowListView;
 import org.robolectric.shadows.androidx.fragment.FragmentController;
 
 import java.util.ArrayList;
@@ -483,19 +486,46 @@
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
         assertThat(dialog.isShowing()).isTrue();
         assertThat(dialog.getListView().getCount()).isEqualTo(2);
-        ArrayList<View> outViews = new ArrayList<>();
-        dialog.getListView()
-                .findViewsWithText(outViews, TEST_DEVICE_NAME1, View.FIND_VIEWS_WITH_TEXT);
-        assertThat(outViews.size()).isEqualTo(1);
-        View view = Iterables.getOnlyElement(outViews);
-        assertThat(view instanceof CheckedTextView).isTrue();
-        assertThat(((CheckedTextView) view).isChecked()).isTrue();
+        ShadowListView listView = Shadows.shadowOf(dialog.getListView());
+        View view1 = listView.findItemContainingText(TEST_DEVICE_NAME1);
+        assertThat(view1).isNotNull();
+        assertThat(view1 instanceof CheckedTextView).isTrue();
+        assertThat(((CheckedTextView) view1).isChecked()).isTrue();
+        View view2 = listView.findItemContainingText(TEST_DEVICE_NAME2);
+        assertThat(view2).isNotNull();
+        assertThat(view2 instanceof CheckedTextView).isTrue();
+        assertThat(((CheckedTextView) view2).isChecked()).isFalse();
+
         verify(mFeatureFactory.metricsFeatureProvider)
                 .visible(
                         /* context= */ eq(null),
                         /* source= */ anyInt(),
                         eq(SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO),
                         /* latency= */ anyInt());
+
+        LeAudioProfile leAudioProfile = mock(LeAudioProfile.class);
+        when(mBtProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile);
+
+        // Perform click to switch call audio device by set active
+        mSetFlagsRule.disableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
+        int index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME2);
+        listView.performItemClick(index);
+        shadowOf(Looper.getMainLooper()).idle();
+        assertThat(((CheckedTextView) view1).isChecked()).isFalse();
+        assertThat(((CheckedTextView) view2).isChecked()).isTrue();
+        verify(mCachedDevice3).setActive();
+        verify(leAudioProfile, never()).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID2);
+
+        // Perform click to switch call audio device with API
+        mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
+        Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID2);
+        index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME1);
+        listView.performItemClick(index);
+        shadowOf(Looper.getMainLooper()).idle();
+        assertThat(((CheckedTextView) view1).isChecked()).isTrue();
+        assertThat(((CheckedTextView) view2).isChecked()).isFalse();
+        verify(mCachedDevice1, never()).setActive();
+        verify(leAudioProfile).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID1);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
index a49d0c1..4a4a167 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java
@@ -584,6 +584,7 @@
     public void testInCallState_showCallStateTitleAndSetActiveOnDeviceClick() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+        mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
                 BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -609,6 +610,7 @@
     public void testInCallState_enableHysteresisFix_setAndSaveActiveOnDeviceClick() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
         mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+        mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
                 BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
index c96a086..b609cdd 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
@@ -198,6 +198,7 @@
     @Test
     public void handleUserTriggeredDeviceConnected_inCall_setActive() {
         mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+        mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
                 BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -218,6 +219,7 @@
     @Test
     public void handleUserTriggeredDeviceConnected_inCall_enableHysteresisFix_setAndSaveActive() {
         mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
+        mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID,
                 BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -452,6 +454,7 @@
 
     @Test
     public void handleDeviceConnected_inCall_doNothing() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API);
         when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
         setUpBroadcast(true);
         when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());