diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java index 395647ca84a..786d07741e2 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java @@ -41,7 +41,9 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.UiThread; import androidx.annotation.VisibleForTesting; +import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; @@ -69,7 +71,6 @@ import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; @@ -113,14 +114,21 @@ public class AudioSharingSwitchBarController extends BasePreferenceController private final Executor mExecutor; private final MetricsFeatureProvider mMetricsFeatureProvider; private final OnAudioSharingStateChangedListener mListener; + @VisibleForTesting IntentFilter mIntentFilter; private Map> mGroupedConnectedDevices = new HashMap<>(); @Nullable private AudioSharingDeviceItem mTargetActiveItem; private List mDeviceItemsForSharing = new ArrayList<>(); - @VisibleForTesting IntentFilter mIntentFilter; private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false); private AtomicInteger mIntentHandleStage = new AtomicInteger(StartIntentHandleStage.TO_HANDLE.ordinal()); + // The sinks in adding source process. We show the progress dialog based on this list. private CopyOnWriteArrayList mSinksInAdding = new CopyOnWriteArrayList<>(); + // The primary/active sinks in adding source process. + // To avoid users advance to share then pair flow before the primary/active sinks successfully + // join the audio sharing, we will wait for the process complete for this list of sinks and then + // popup audio sharing dialog with options to pair new device. + private CopyOnWriteArrayList mSinksToWaitFor = new CopyOnWriteArrayList<>(); + private AtomicBoolean mStoppingSharing = new AtomicBoolean(false); @VisibleForTesting BroadcastReceiver mReceiver = @@ -153,6 +161,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController public void onBroadcastStartFailed(int reason) { Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason); updateSwitch(); + showRetryDialog(); mMetricsFeatureProvider.action( mContext, SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED, @@ -178,7 +187,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController + reason + ", broadcastId = " + broadcastId); + mStoppingSharing.compareAndSet(true, false); updateSwitch(); + AudioSharingUtils.postOnMainThread(mContext, + () -> dismissStaleDialogsOtherThanRetryDialog()); AudioSharingUtils.toastMessage( mContext, mContext.getString(R.string.audio_sharing_sharing_stopped_label)); @@ -219,7 +231,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController TAG, "Skip handleOnBroadcastReady: null assistant or " + "sink has active local source."); - cleanUp(); + cleanUpStatesForStartSharing(); return; } handleOnBroadcastReady(); @@ -264,17 +276,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController + source + ", reason = " + reason); - mMetricsFeatureProvider.action( - mContext, - SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, - SettingsEnums.AUDIO_SHARING_SETTINGS); - AudioSharingUtils.toastMessage( - mContext, - String.format( - Locale.US, - "Fail to add source to %s reason %d", - sink.getAddress(), - reason)); + if (mSinksInAdding.contains(sink)) { + stopAudioSharing(); + showRetryDialog(); + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); + } } @Override @@ -298,6 +307,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController @NonNull BluetoothDevice sink, int sourceId, @NonNull BluetoothLeBroadcastReceiveState state) { + if (mStoppingSharing.get()) { + Log.d(TAG, "Skip onReceiveStateChanged, stopping broadcast"); + return; + } if (BluetoothUtils.isConnected(state)) { if (mSinksInAdding.contains(sink)) { mSinksInAdding.remove(sink); @@ -305,6 +318,22 @@ public class AudioSharingSwitchBarController extends BasePreferenceController dismissLoadingStateDialogIfNeeded(); Log.d(TAG, "onReceiveStateChanged() connected, sink = " + sink + ", remaining sinks = " + mSinksInAdding); + if (mSinksToWaitFor.contains(sink)) { + mSinksToWaitFor.remove(sink); + if (mSinksToWaitFor.isEmpty()) { + // To avoid users advance to share then pair flow before the + // primary/active sinks successfully join the audio sharing, + // popup dialog till adding source complete for mSinksToWaitFor. + Pair[] eventData = + AudioSharingUtils.buildAudioSharingDialogEventData( + SettingsEnums.AUDIO_SHARING_SETTINGS, + SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE, + /* userTriggered= */ false, + /* deviceCountInSharing= */ 1, + /* candidateDeviceCount= */ 0); + showAudioSharingDialog(eventData); + } + } } } }; @@ -411,6 +440,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController return; } stopAudioSharing(); + mMetricsFeatureProvider.action( + mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF); } } @@ -553,9 +584,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController private void stopAudioSharing() { if (mBroadcast != null) { - mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId()); - mMetricsFeatureProvider.action( - mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF); + int broadcastId = mBroadcast.getLatestBroadcastId(); + if (broadcastId != -1) { + mBroadcast.stopBroadcast(broadcastId); + mStoppingSharing.compareAndSet(false, true); + mSinksInAdding.clear(); + mSinksToWaitFor.clear(); + } + cleanUpStatesForStartSharing(); } } @@ -617,11 +653,22 @@ public class AudioSharingSwitchBarController extends BasePreferenceController /* userTriggered= */ false, /* deviceCountInSharing= */ targetActiveSinks.isEmpty() ? 0 : 1, /* candidateDeviceCount= */ mDeviceItemsForSharing.size()); + // Auto add primary/active sinks w/o user interactions. if (!targetActiveSinks.isEmpty() && mTargetActiveItem != null) { Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks."); addSourceToTargetSinks(targetActiveSinks, mTargetActiveItem.getName()); + // To avoid users advance to share then pair flow before the primary/active sinks + // successfully join the audio sharing, save the primary/active sinks in mSinksToWaitFor + // and popup dialog till adding source complete for these sinks. + if (mDeviceItemsForSharing.isEmpty()) { + mSinksToWaitFor.clear(); + mSinksToWaitFor.addAll(targetActiveSinks); + } mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING); mTargetActiveItem = null; + // When audio sharing page is brought up by intent with EXTRA_START_LE_AUDIO_SHARING + // == true, plus there is one active lea headset and one connected lea headset, we + // should auto add these sinks without user interactions. if (mIntentHandleStage.compareAndSet( StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(), StartIntentHandleStage.HANDLED.ordinal()) @@ -631,31 +678,42 @@ public class AudioSharingSwitchBarController extends BasePreferenceController List targetSinks = mGroupedConnectedDevices.getOrDefault( target.getGroupId(), ImmutableList.of()); addSourceToTargetSinks(targetSinks, target.getName()); - cleanUp(); + cleanUpStatesForStartSharing(); // TODO: Add metric for auto add by intent return; } } + // Still mark intent as handled if early returned due to preconditions not met mIntentHandleStage.compareAndSet( StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(), StartIntentHandleStage.HANDLED.ordinal()); if (mFragment == null) { Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment."); + // Clean up states before early return. dismissLoadingStateDialogIfNeeded(); - cleanUp(); + cleanUpStatesForStartSharing(); return; } - showDialog(eventData); + // To avoid users advance to share then pair flow before the primary/active sinks + // successfully join the audio sharing, popup dialog till adding source complete for + // mSinksToWaitFor. + if (mSinksToWaitFor.isEmpty() && !mStoppingSharing.get()) { + showAudioSharingDialog(eventData); + } } - private void showDialog(Pair[] eventData) { + private void showAudioSharingDialog(Pair[] eventData) { + if (!BluetoothUtils.isBroadcasting(mBtManager)) { + Log.d(TAG, "Skip showAudioSharingDialog, broadcast is stopped"); + return; + } AudioSharingDialogFragment.DialogEventListener listener = new AudioSharingDialogFragment.DialogEventListener() { @Override public void onPositiveClick() { // Could go to other pages, dismiss the loading dialog. dismissLoadingStateDialogIfNeeded(); - cleanUp(); + cleanUpStatesForStartSharing(); } @Override @@ -663,14 +721,14 @@ public class AudioSharingSwitchBarController extends BasePreferenceController List targetSinks = mGroupedConnectedDevices.getOrDefault( item.getGroupId(), ImmutableList.of()); addSourceToTargetSinks(targetSinks, item.getName()); - cleanUp(); + cleanUpStatesForStartSharing(); } @Override public void onCancelClick() { // Could go to other pages, dismiss the loading dialog. dismissLoadingStateDialogIfNeeded(); - cleanUp(); + cleanUpStatesForStartSharing(); } }; AudioSharingUtils.postOnMainThread( @@ -684,6 +742,36 @@ public class AudioSharingSwitchBarController extends BasePreferenceController }); } + private void showRetryDialog() { + AudioSharingUtils.postOnMainThread(mContext, + () -> { + // Remove all opening dialogs before show retry dialog + dismissStaleDialogsOtherThanRetryDialog(); + AudioSharingRetryDialogFragment.show(mFragment); + }); + } + + @UiThread + private void dismissStaleDialogsOtherThanRetryDialog() { + List fragments = new ArrayList(); + try { + if (mFragment != null) { + fragments = + mFragment.getChildFragmentManager().getFragments(); + } + } catch (Exception e) { + Log.e(TAG, "Fail to dismiss stale dialogs: " + e.getMessage()); + } + for (Fragment fragment : fragments) { + if (fragment != null && fragment instanceof DialogFragment + && !(fragment instanceof AudioSharingRetryDialogFragment) + && ((DialogFragment) fragment).getDialog() != null) { + Log.d(TAG, "Remove stale dialog = " + fragment.getTag()); + ((DialogFragment) fragment).dismiss(); + } + } + } + private static final class MainSwitchAccessibilityDelegate extends View.AccessibilityDelegate { @Override public boolean onRequestSendAccessibilityEvent( @@ -742,10 +830,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController private void addSourceToTargetSinks(List targetActiveSinks, @NonNull String sinkName) { mSinksInAdding.addAll(targetActiveSinks); - AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager); // TODO: move to res once finalized String loadingMessage = "Sharing with " + sinkName + "..."; showLoadingStateDialog(loadingMessage); + AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager); } private void showLoadingStateDialog(@NonNull String loadingMessage) { @@ -760,7 +848,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController } } - private void cleanUp() { + private void cleanUpStatesForStartSharing() { mGroupedConnectedDevices.clear(); mDeviceItemsForSharing.clear(); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java index eb2083ebe7b..415762b1879 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java @@ -146,6 +146,7 @@ public class AudioSharingSwitchBarControllerTest { @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private VolumeControlProfile mVolumeControl; @Mock private BluetoothLeBroadcastMetadata mMetadata; + @Mock private BluetoothLeBroadcastReceiveState mState; @Mock private CompoundButton mBtnView; @Mock private CachedBluetoothDevice mCachedDevice1; @Mock private CachedBluetoothDevice mCachedDevice2; @@ -519,10 +520,9 @@ public class AudioSharingSwitchBarControllerTest { mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1)); - BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); - when(state.getBroadcastId()).thenReturn(1); + when(mState.getBroadcastId()).thenReturn(1); when(mBroadcast.getLatestBroadcastId()).thenReturn(1); - when(mAssistant.getAllSources(mDevice2)).thenReturn(ImmutableList.of(state)); + when(mAssistant.getAllSources(mDevice2)).thenReturn(ImmutableList.of(mState)); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); doNothing().when(mBroadcast).startPrivateBroadcast(); mController.onCheckedChanged(mBtnView, /* isChecked= */ true); @@ -549,14 +549,77 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_showJoinAudioSharingDialog() { + public void onPlaybackStarted_singleActiveDevice_showJoinAudioSharingDialog() { + FeatureFlagUtils.setEnabled( + mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); + when(mBtnView.isEnabled()).thenReturn(true); + when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2)); + when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of()); + doNothing().when(mBroadcast).startPrivateBroadcast(); + mController.onCheckedChanged(mBtnView, /* isChecked= */ true); + shadowOf(Looper.getMainLooper()).idle(); + + verify(mBroadcast).startPrivateBroadcast(); + List childFragments = mParentFragment.getChildFragmentManager().getFragments(); + assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly( + AudioSharingLoadingStateDialogFragment.class.getName()); + + when(mBroadcast.isEnabled(null)).thenReturn(true); + when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); + mController.mBroadcastCallback.onPlaybackStarted(0, 0); + shadowOf(Looper.getMainLooper()).idle(); + + verify(mFeatureFactory.metricsFeatureProvider) + .action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING)); + + when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L)); + mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice2, /* sourceId= */ 1, + mState); + shadowOf(Looper.getMainLooper()).idle(); + + childFragments = mParentFragment.getChildFragmentManager().getFragments(); + assertThat(childFragments) + .comparingElementsUsing(CLAZZNAME_EQUALS) + .containsExactly(AudioSharingDialogFragment.class.getName()); + + Pair[] eventData = new Pair[0]; + for (Fragment fragment : childFragments) { + if (fragment instanceof AudioSharingDialogFragment) { + eventData = ((AudioSharingDialogFragment) fragment).getEventData(); + break; + } + } + assertThat(eventData) + .asList() + .containsExactly( + Pair.create( + AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(), + SettingsEnums.AUDIO_SHARING_SETTINGS), + Pair.create( + AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(), + SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE), + Pair.create( + AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0), + Pair.create( + AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING + .ordinal(), + 1), + Pair.create( + AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT + .ordinal(), + 0)); + + childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss()); + } + + @Test + public void onPlaybackStarted_oneActiveOnConnected_showJoinAudioSharingDialog() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1)); when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of()); doNothing().when(mBroadcast).startPrivateBroadcast(); - when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); mController.onCheckedChanged(mBtnView, /* isChecked= */ true); shadowOf(Looper.getMainLooper()).idle(); @@ -570,6 +633,8 @@ public class AudioSharingSwitchBarControllerTest { String expectedMessage = "Starting audio stream..."; checkLoadingStateDialogMessage(loadingFragment, expectedMessage); + when(mBroadcast.isEnabled(null)).thenReturn(true); + when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); mController.mBroadcastCallback.onPlaybackStarted(0, 0); shadowOf(Looper.getMainLooper()).idle(); @@ -616,18 +681,19 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_clickShareBtnOnDialog_addSource() { + public void onPlaybackStarted_oneActiveOnConnected_clickShareBtnOnDialog_addSource() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1)); when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of()); - when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); doNothing().when(mBroadcast).startPrivateBroadcast(); mController.onCheckedChanged(mBtnView, /* isChecked= */ true); shadowOf(Looper.getMainLooper()).idle(); verify(mBroadcast).startPrivateBroadcast(); + when(mBroadcast.isEnabled(null)).thenReturn(true); + when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); mController.mBroadcastCallback.onPlaybackStarted(0, 0); shadowOf(Looper.getMainLooper()).idle(); @@ -656,18 +722,19 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_clickCancelBtnOnDialog_doNothing() { + public void onPlaybackStarted_oneActiveOnConnected_clickCancelBtnOnDialog_doNothing() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1)); when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of()); - when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); doNothing().when(mBroadcast).startPrivateBroadcast(); mController.onCheckedChanged(mBtnView, /* isChecked= */ true); shadowOf(Looper.getMainLooper()).idle(); verify(mBroadcast).startPrivateBroadcast(); + when(mBroadcast.isEnabled(null)).thenReturn(true); + when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); mController.mBroadcastCallback.onPlaybackStarted(0, 0); shadowOf(Looper.getMainLooper()).idle(); @@ -754,14 +821,50 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void testAssistantCallbacks_onSourceAddFailed_logAction() { + public void testAssistantCallbacks_onSourceAddFailed_twoDevices_showRetryAndLogAction() { + FeatureFlagUtils.setEnabled( + mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); + when(mBtnView.isEnabled()).thenReturn(true); + when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1)); + when(mAssistant.getAllSources(any(BluetoothDevice.class))).thenReturn(ImmutableList.of()); + doNothing().when(mBroadcast).startPrivateBroadcast(); + mController.onCheckedChanged(mBtnView, /* isChecked= */ true); + shadowOf(Looper.getMainLooper()).idle(); + + verify(mBroadcast).startPrivateBroadcast(); + + when(mBroadcast.isEnabled(null)).thenReturn(true); + when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); + mController.mBroadcastCallback.onPlaybackStarted(0, 0); + shadowOf(Looper.getMainLooper()).idle(); + + verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false); + + AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + assertThat(dialog).isNotNull(); + View btnView = dialog.findViewById(R.id.positive_btn); + assertThat(btnView).isNotNull(); + btnView.performClick(); + shadowMainLooper().idle(); + + verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false); + assertThat(dialog.isShowing()).isFalse(); + mController.mBroadcastAssistantCallback.onSourceAddFailed( mDevice1, mMetadata, /* reason= */ 1); + shadowMainLooper().idle(); + + // Loading state dialog shows sharing state for the user chosen sink. + List childFragments = mParentFragment.getChildFragmentManager().getFragments(); + assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly( + AudioSharingRetryDialogFragment.class.getName()); verify(mFeatureFactory.metricsFeatureProvider) .action( mContext, SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, SettingsEnums.AUDIO_SHARING_SETTINGS); + + childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss()); } @Test @@ -772,10 +875,9 @@ public class AudioSharingSwitchBarControllerTest { assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly( AudioSharingLoadingStateDialogFragment.class.getName()); - BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); - when(state.getBisSyncState()).thenReturn(ImmutableList.of(1L)); + when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L)); mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1, - state); + mState); shadowOf(Looper.getMainLooper()).idle(); childFragments = mParentFragment.getChildFragmentManager().getFragments(); assertThat(childFragments).isEmpty(); @@ -783,11 +885,9 @@ public class AudioSharingSwitchBarControllerTest { @Test public void testAssistantCallbacks_doNothing() { - BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); - // Do nothing mController.mBroadcastAssistantCallback.onReceiveStateChanged( - mDevice1, /* sourceId= */ 1, state); + mDevice1, /* sourceId= */ 1, mState); mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1);