Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea68bb08 authored by Yiyi Shen's avatar Yiyi Shen Committed by Android (Google) Code Review
Browse files

Merge "[Audiosharing] Change main toggle enable conditions." into main

parents e376c586 439873d0
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -379,7 +378,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
            if (FeatureFlagUtils.isEnabled(
                    mContext,
                    FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST)
                    && mAssistant.getAllConnectedDevices().isEmpty()) {
                    && hasEmptyConnectedSink()) {
                // Pop up dialog to ask users to connect at least one lea buds before audio sharing.
                AudioSharingUtils.postOnMainThread(
                        mContext,
@@ -435,8 +434,12 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
    }

    @Override
    public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
        if (activeDevice != null && bluetoothProfile == BluetoothProfile.LE_AUDIO) {
    public void onActiveDeviceChanged(@Nullable CachedBluetoothDevice activeDevice,
            int bluetoothProfile) {
        if (activeDevice != null) {
            Log.d(TAG, "onActiveDeviceChanged: device = "
                    + activeDevice.getDevice().getAnonymizedAddress()
                    + ", profile = " + bluetoothProfile);
            updateSwitch();
        }
    }
@@ -536,13 +539,19 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
                            boolean isBroadcasting = BluetoothUtils.isBroadcasting(mBtManager);
                            boolean hasActiveDevice =
                                    AudioSharingUtils.hasActiveConnectedLeadDevice(mBtManager);
                            boolean hasEmptyConnectedDevice = hasEmptyConnectedSink();
                            boolean isStateReady =
                                    isBluetoothOn()
                                            && AudioSharingUtils.isAudioSharingProfileReady(
                                            mProfileManager)
                                            && (isBroadcasting
                                            // Always enable toggle when no connected sink. We have
                                            // dialog to guide users to connect compatible devices
                                            // for audio sharing.
                                            || hasEmptyConnectedDevice
                                            // Disable toggle till device gets active after
                                            // broadcast ends.
                                            && (isBroadcasting || hasActiveDevice);
                                            || hasActiveDevice);
                            AudioSharingUtils.postOnMainThread(
                                    mContext,
                                    () -> {
@@ -566,6 +575,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
        return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
    }

    private boolean hasEmptyConnectedSink() {
        return mAssistant != null && mAssistant.getAllConnectedDevices().isEmpty();
    }

    private void handleOnBroadcastReady() {
        Pair<Integer, Object>[] eventData =
                AudioSharingUtils.buildAudioSharingDialogEventData(
+5 −8
Original line number Diff line number Diff line
@@ -215,16 +215,13 @@ public class AudioSharingUtils {
            @Nullable LocalBluetoothManager localBtManager) {
        CachedBluetoothDeviceManager deviceManager =
                localBtManager == null ? null : localBtManager.getCachedDeviceManager();
        Map<Integer, List<BluetoothDevice>> groupedConnectedDevices =
                fetchConnectedDevicesByGroupId(localBtManager);
        for (List<BluetoothDevice> devices : groupedConnectedDevices.values()) {
            CachedBluetoothDevice leadDevice = getLeadDevice(deviceManager, devices);
            if (isActiveLeAudioDevice(leadDevice)) {
                return true;
            }
        }
        if (deviceManager == null) {
            Log.d(TAG, "hasActiveConnectedLeadDevice return false due to null device manager.");
            return false;
        }
        return deviceManager.getCachedDevicesCopy().stream().anyMatch(
                BluetoothUtils::isActiveMediaDevice);
    }

    /** Build {@link AudioSharingDeviceItem} from {@link CachedBluetoothDevice}. */
    public static AudioSharingDeviceItem buildAudioSharingDeviceItem(
+48 −17
Original line number Diff line number Diff line
@@ -123,12 +123,13 @@ public class AudioSharingSwitchBarControllerTest {
    private static final String TEST_DEVICE_ANONYMIZED_ADDR2 = "XX:XX:02";
    private static final int TEST_DEVICE_GROUP_ID1 = 1;
    private static final int TEST_DEVICE_GROUP_ID2 = 2;
    private static final Correspondence<Fragment, String> TAG_EQUALS =
    private static final Correspondence<Fragment, String> CLAZZNAME_EQUALS =
            Correspondence.from(
                    (Fragment fragment, String tag) ->
                    (Fragment fragment, String clazzName) ->
                            fragment instanceof DialogFragment
                                    && ((DialogFragment) fragment).getTag() != null
                                    && ((DialogFragment) fragment).getTag().equals(tag),
                                    && ((DialogFragment) fragment).getClass().getName() != null
                                    && ((DialogFragment) fragment).getClass().getName().equals(
                                    clazzName),
                    "is equal to");

    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@@ -343,6 +344,18 @@ public class AudioSharingSwitchBarControllerTest {
        assertThat(mSwitchBar.isEnabled()).isTrue();
    }

    @Test
    public void onStart_flagOn_updateSwitch() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        when(mBroadcast.isEnabled(null)).thenReturn(false);
        when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
        mController.onStart(mLifecycleOwner);
        shadowOf(Looper.getMainLooper()).idle();

        assertThat(mSwitchBar.isChecked()).isFalse();
        assertThat(mSwitchBar.isEnabled()).isTrue();
    }

    @Test
    public void onStop_flagOff_doNothing() {
        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
@@ -398,15 +411,21 @@ public class AudioSharingSwitchBarControllerTest {
    }

    @Test
    public void onCheckedChangedToChecked_noConnectedLeaDevices_flagOn_notStartAudioSharing() {
    public void onCheckedChangedToChecked_noConnectedLeaDevices_flagOn_showDialog() {
        FeatureFlagUtils.setEnabled(
                mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
        when(mBtnView.isEnabled()).thenReturn(true);
        when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of());
        doNothing().when(mBroadcast).startPrivateBroadcast();
        mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
        shadowOf(Looper.getMainLooper()).idle();

        assertThat(mSwitchBar.isChecked()).isFalse();
        verify(mBroadcast, never()).startPrivateBroadcast();
        List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
        assertThat(childFragments)
                .comparingElementsUsing(CLAZZNAME_EQUALS)
                .containsExactly(AudioSharingConfirmDialogFragment.class.getName());
    }

    @Test
@@ -526,8 +545,8 @@ public class AudioSharingSwitchBarControllerTest {

        List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
        assertThat(childFragments)
                .comparingElementsUsing(TAG_EQUALS)
                .containsExactly(AudioSharingDialogFragment.tag());
                .comparingElementsUsing(CLAZZNAME_EQUALS)
                .containsExactly(AudioSharingDialogFragment.class.getName());

        AudioSharingDialogFragment fragment =
                (AudioSharingDialogFragment) Iterables.getOnlyElement(childFragments);
@@ -613,6 +632,8 @@ public class AudioSharingSwitchBarControllerTest {
        mSwitchBar.setChecked(false);
        when(mBroadcast.isEnabled(any())).thenReturn(false);
        when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2));
        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
                ImmutableList.of(mCachedDevice1, mCachedDevice2));
        mController.mBroadcastCallback.onBroadcastStartFailed(/* reason= */ 1);
        shadowOf(Looper.getMainLooper()).idle();
        assertThat(mSwitchBar.isChecked()).isFalse();
@@ -706,6 +727,8 @@ public class AudioSharingSwitchBarControllerTest {
        mSwitchBar.setEnabled(false);
        when(mBroadcast.isEnabled(null)).thenReturn(false);
        when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
                ImmutableList.of(mCachedDevice2, mCachedDevice1));
        mController.onActiveDeviceChanged(mCachedDevice2, BluetoothProfile.LE_AUDIO);
        shadowOf(Looper.getMainLooper()).idle();
        assertThat(mSwitchBar.isChecked()).isFalse();
@@ -713,16 +736,24 @@ public class AudioSharingSwitchBarControllerTest {
    }

    @Test
    public void onActiveDeviceChanged_nullActiveDevice_doNothing() {
        mController.onActiveDeviceChanged(/* activeDevice= */ null, BluetoothProfile.LE_AUDIO);
    public void onActiveDeviceChanged_a2dpProfile_updateSwitch() {
        mSwitchBar.setChecked(true);
        mSwitchBar.setEnabled(false);
        when(mBroadcast.isEnabled(null)).thenReturn(false);
        when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2));
        when(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false);
        when(mCachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).thenReturn(true);
        when(mDeviceManager.getCachedDevicesCopy()).thenReturn(
                ImmutableList.of(mCachedDevice1, mCachedDevice2));
        mController.onActiveDeviceChanged(mCachedDevice2, BluetoothProfile.A2DP);
        shadowOf(Looper.getMainLooper()).idle();
        verify(mSwitchBar, never()).setEnabled(anyBoolean());
        verify(mSwitchBar, never()).setChecked(anyBoolean());
        assertThat(mSwitchBar.isChecked()).isFalse();
        verify(mSwitchBar).setEnabled(true);
    }

    @Test
    public void onActiveDeviceChanged_notLeaProfile_doNothing() {
        mController.onActiveDeviceChanged(mCachedDevice2, BluetoothProfile.HEADSET);
    public void onActiveDeviceChanged_nullActiveDevice_doNothing() {
        mController.onActiveDeviceChanged(/* activeDevice= */ null, BluetoothProfile.LE_AUDIO);
        shadowOf(Looper.getMainLooper()).idle();
        verify(mSwitchBar, never()).setEnabled(anyBoolean());
        verify(mSwitchBar, never()).setChecked(anyBoolean());