Loading src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java +10 −3 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.preference.PreferenceScreen; Loading @@ -48,7 +49,9 @@ public class AudioStreamButtonController extends BasePreferenceController private static final String TAG = "AudioStreamButtonController"; private static final String KEY = "audio_stream_button"; private static final int SOURCE_ORIGIN_REPOSITORY = SourceOriginForLogging.REPOSITORY.ordinal(); private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = @VisibleForTesting final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new AudioStreamsBroadcastAssistantCallback() { @Override public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) { Loading Loading @@ -97,8 +100,7 @@ public class AudioStreamButtonController extends BasePreferenceController } }; private final AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance(); private AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance(); private final Executor mExecutor; private final AudioStreamsHelper mAudioStreamsHelper; private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant; Loading Loading @@ -228,4 +230,9 @@ public class AudioStreamButtonController extends BasePreferenceController void init(int broadcastId) { mBroadcastId = broadcastId; } @VisibleForTesting void setAudioStreamsRepositoryForTesting(AudioStreamsRepository repository) { mAudioStreamsRepository = repository; } } src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java +6 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.text.TextUtils; import android.util.Log; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.settings.R; import com.android.settings.bluetooth.Utils; Loading @@ -43,9 +44,12 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; public class AudioStreamConfirmDialog extends InstrumentedDialogFragment { private static final String TAG = "AudioStreamConfirmDialog"; private static final int DEFAULT_DEVICE_NAME = R.string.audio_streams_dialog_default_device; @VisibleForTesting static final int DEFAULT_DEVICE_NAME = R.string.audio_streams_dialog_default_device; private Context mContext; @Nullable private Activity mActivity; @VisibleForTesting @Nullable Activity mActivity; @Nullable private BluetoothLeBroadcastMetadata mBroadcastMetadata; @Nullable private BluetoothDevice mConnectedDevice; private int mAudioStreamConfirmDialogId = SettingsEnums.PAGE_UNKNOWN; Loading src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderController.java +3 −1 Original line number Diff line number Diff line Loading @@ -54,7 +54,9 @@ public class AudioStreamHeaderController extends BasePreferenceController private final Executor mExecutor; private final AudioStreamsHelper mAudioStreamsHelper; @Nullable private final LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant; private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = @VisibleForTesting final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new AudioStreamsBroadcastAssistantCallback() { @Override public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) { Loading src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java +0 −11 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import androidx.annotation.Nullable; Loading Loading @@ -63,11 +62,6 @@ public class AudioStreamsDashboardFragment extends DashboardFragment { return R.xml.bluetooth_le_audio_streams; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onAttach(Context context) { super.onAttach(context); Loading @@ -91,11 +85,6 @@ public class AudioStreamsDashboardFragment extends DashboardFragment { } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Loading tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonControllerTest.java +177 −2 Original line number Diff line number Diff line Loading @@ -16,22 +16,36 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; 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.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.content.Context; import android.view.View; import androidx.lifecycle.LifecycleOwner; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.widget.ActionButtonsPreference; import org.junit.After; Loading @@ -39,14 +53,17 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; @RunWith(RobolectricTestRunner.class) @Config( Loading @@ -63,14 +80,23 @@ public class AudioStreamButtonControllerTest { @Mock private AudioStreamsHelper mAudioStreamsHelper; @Mock private PreferenceScreen mScreen; @Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState; @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private AudioStreamsRepository mRepository; @Mock private ActionButtonsPreference mPreference; private Lifecycle mLifecycle; private LifecycleOwner mLifecycleOwner; private FakeFeatureFactory mFeatureFactory; private AudioStreamButtonController mController; @Before public void setUp() { ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper); when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mAssistant); mFeatureFactory = FakeFeatureFactory.setupForTest(); mController = new AudioStreamButtonController(mContext, KEY); mController.init(BROADCAST_ID); mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); when(mScreen.findPreference(KEY)).thenReturn(mPreference); when(mPreference.getContext()).thenReturn(mContext); when(mPreference.setButton1Text(anyInt())).thenReturn(mPreference); Loading @@ -85,6 +111,40 @@ public class AudioStreamButtonControllerTest { ShadowAudioStreamsHelper.reset(); } @Test public void onStart_registerCallbacks() { mController.onStart(mLifecycleOwner); verify(mAssistant) .registerServiceCallBack( any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void onStart_profileNull_doNothing() { when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(null); mController = new AudioStreamButtonController(mContext, KEY); mController.onStart(mLifecycleOwner); verify(mAssistant, never()) .registerServiceCallBack( any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void onStop_unregisterCallbacks() { mController.onStop(mLifecycleOwner); verify(mAssistant) .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void onStop_profileNull_doNothing() { when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(null); mController = new AudioStreamButtonController(mContext, KEY); mController.onStop(mLifecycleOwner); verify(mAssistant, never()) .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void testDisplayPreference_sourceConnected_setDisconnectButton() { when(mAudioStreamsHelper.getAllConnectedSources()) Loading @@ -96,18 +156,133 @@ public class AudioStreamButtonControllerTest { verify(mPreference).setButton1Enabled(true); verify(mPreference).setButton1Text(R.string.audio_streams_disconnect); verify(mPreference).setButton1Icon(com.android.settings.R.drawable.ic_settings_close); verify(mPreference).setButton1OnClickListener(any(View.OnClickListener.class)); ArgumentCaptor<View.OnClickListener> listenerCaptor = ArgumentCaptor.forClass(View.OnClickListener.class); verify(mPreference).setButton1OnClickListener(listenerCaptor.capture()); var listener = listenerCaptor.getValue(); assertThat(listener).isNotNull(); listener.onClick(mock(View.class)); verify(mAudioStreamsHelper).removeSource(BROADCAST_ID); verify(mPreference).setButton1Enabled(false); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_LEAVE_BUTTON_CLICK)); } @Test public void testDisplayPreference_sourceNotConnected_setConnectButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.setAudioStreamsRepositoryForTesting(mRepository); var metadataToRejoin = mock(BluetoothLeBroadcastMetadata.class); when(mRepository.getSavedMetadata(any(), anyInt())).thenReturn(metadataToRejoin); mController.displayPreference(mScreen); verify(mPreference).setButton1Enabled(true); verify(mPreference).setButton1Text(R.string.audio_streams_connect); verify(mPreference).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); verify(mPreference).setButton1OnClickListener(any(View.OnClickListener.class)); ArgumentCaptor<View.OnClickListener> listenerCaptor = ArgumentCaptor.forClass(View.OnClickListener.class); verify(mPreference).setButton1OnClickListener(listenerCaptor.capture()); var listener = listenerCaptor.getValue(); assertThat(listener).isNotNull(); listener.onClick(mock(View.class)); verify(mAudioStreamsHelper).addSource(metadataToRejoin); verify(mPreference).setButton1Enabled(false); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN), anyInt()); } @Test public void testCallback_onSourceRemoved_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceRemoved( mock(BluetoothDevice.class), /* sourceId= */ 0, /* reason= */ 0); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_connect); verify(mPreference, times(2)).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); } @Test public void testCallback_onSourceRemovedFailed_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()) .thenReturn(List.of(mBroadcastReceiveState)); when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceRemoveFailed( mock(BluetoothDevice.class), /* sourceId= */ 0, /* reason= */ 0); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_LEAVE_FAILED)); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_disconnect); verify(mPreference, times(2)) .setButton1Icon(com.android.settings.R.drawable.ic_settings_close); } @Test public void testCallback_onReceiveStateChanged_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()) .thenReturn(List.of(mBroadcastReceiveState)); when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); List<Long> bisSyncState = new ArrayList<>(); bisSyncState.add(1L); when(state.getBisSyncState()).thenReturn(bisSyncState); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onReceiveStateChanged( mock(BluetoothDevice.class), /* sourceId= */ 0, state); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED), anyInt()); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_disconnect); verify(mPreference, times(2)) .setButton1Icon(com.android.settings.R.drawable.ic_settings_close); } @Test public void testCallback_onSourceAddFailed_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceAddFailed( mock(BluetoothDevice.class), mock(BluetoothLeBroadcastMetadata.class), /* reason= */ 0); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_OTHER), anyInt()); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_connect); verify(mPreference, times(2)).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); } @Test public void testCallback_onSourceLost_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 0); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_connect); verify(mPreference, times(2)).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); } } Loading
src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java +10 −3 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.preference.PreferenceScreen; Loading @@ -48,7 +49,9 @@ public class AudioStreamButtonController extends BasePreferenceController private static final String TAG = "AudioStreamButtonController"; private static final String KEY = "audio_stream_button"; private static final int SOURCE_ORIGIN_REPOSITORY = SourceOriginForLogging.REPOSITORY.ordinal(); private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = @VisibleForTesting final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new AudioStreamsBroadcastAssistantCallback() { @Override public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) { Loading Loading @@ -97,8 +100,7 @@ public class AudioStreamButtonController extends BasePreferenceController } }; private final AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance(); private AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance(); private final Executor mExecutor; private final AudioStreamsHelper mAudioStreamsHelper; private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant; Loading Loading @@ -228,4 +230,9 @@ public class AudioStreamButtonController extends BasePreferenceController void init(int broadcastId) { mBroadcastId = broadcastId; } @VisibleForTesting void setAudioStreamsRepositoryForTesting(AudioStreamsRepository repository) { mAudioStreamsRepository = repository; } }
src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamConfirmDialog.java +6 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.text.TextUtils; import android.util.Log; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.settings.R; import com.android.settings.bluetooth.Utils; Loading @@ -43,9 +44,12 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; public class AudioStreamConfirmDialog extends InstrumentedDialogFragment { private static final String TAG = "AudioStreamConfirmDialog"; private static final int DEFAULT_DEVICE_NAME = R.string.audio_streams_dialog_default_device; @VisibleForTesting static final int DEFAULT_DEVICE_NAME = R.string.audio_streams_dialog_default_device; private Context mContext; @Nullable private Activity mActivity; @VisibleForTesting @Nullable Activity mActivity; @Nullable private BluetoothLeBroadcastMetadata mBroadcastMetadata; @Nullable private BluetoothDevice mConnectedDevice; private int mAudioStreamConfirmDialogId = SettingsEnums.PAGE_UNKNOWN; Loading
src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderController.java +3 −1 Original line number Diff line number Diff line Loading @@ -54,7 +54,9 @@ public class AudioStreamHeaderController extends BasePreferenceController private final Executor mExecutor; private final AudioStreamsHelper mAudioStreamsHelper; @Nullable private final LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant; private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = @VisibleForTesting final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new AudioStreamsBroadcastAssistantCallback() { @Override public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) { Loading
src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java +0 −11 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import androidx.annotation.Nullable; Loading Loading @@ -63,11 +62,6 @@ public class AudioStreamsDashboardFragment extends DashboardFragment { return R.xml.bluetooth_le_audio_streams; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onAttach(Context context) { super.onAttach(context); Loading @@ -91,11 +85,6 @@ public class AudioStreamsDashboardFragment extends DashboardFragment { } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Loading
tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonControllerTest.java +177 −2 Original line number Diff line number Diff line Loading @@ -16,22 +16,36 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; 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.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.content.Context; import android.view.View; import androidx.lifecycle.LifecycleOwner; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.widget.ActionButtonsPreference; import org.junit.After; Loading @@ -39,14 +53,17 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.Executor; @RunWith(RobolectricTestRunner.class) @Config( Loading @@ -63,14 +80,23 @@ public class AudioStreamButtonControllerTest { @Mock private AudioStreamsHelper mAudioStreamsHelper; @Mock private PreferenceScreen mScreen; @Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState; @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; @Mock private AudioStreamsRepository mRepository; @Mock private ActionButtonsPreference mPreference; private Lifecycle mLifecycle; private LifecycleOwner mLifecycleOwner; private FakeFeatureFactory mFeatureFactory; private AudioStreamButtonController mController; @Before public void setUp() { ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper); when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mAssistant); mFeatureFactory = FakeFeatureFactory.setupForTest(); mController = new AudioStreamButtonController(mContext, KEY); mController.init(BROADCAST_ID); mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); when(mScreen.findPreference(KEY)).thenReturn(mPreference); when(mPreference.getContext()).thenReturn(mContext); when(mPreference.setButton1Text(anyInt())).thenReturn(mPreference); Loading @@ -85,6 +111,40 @@ public class AudioStreamButtonControllerTest { ShadowAudioStreamsHelper.reset(); } @Test public void onStart_registerCallbacks() { mController.onStart(mLifecycleOwner); verify(mAssistant) .registerServiceCallBack( any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void onStart_profileNull_doNothing() { when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(null); mController = new AudioStreamButtonController(mContext, KEY); mController.onStart(mLifecycleOwner); verify(mAssistant, never()) .registerServiceCallBack( any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void onStop_unregisterCallbacks() { mController.onStop(mLifecycleOwner); verify(mAssistant) .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void onStop_profileNull_doNothing() { when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(null); mController = new AudioStreamButtonController(mContext, KEY); mController.onStop(mLifecycleOwner); verify(mAssistant, never()) .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); } @Test public void testDisplayPreference_sourceConnected_setDisconnectButton() { when(mAudioStreamsHelper.getAllConnectedSources()) Loading @@ -96,18 +156,133 @@ public class AudioStreamButtonControllerTest { verify(mPreference).setButton1Enabled(true); verify(mPreference).setButton1Text(R.string.audio_streams_disconnect); verify(mPreference).setButton1Icon(com.android.settings.R.drawable.ic_settings_close); verify(mPreference).setButton1OnClickListener(any(View.OnClickListener.class)); ArgumentCaptor<View.OnClickListener> listenerCaptor = ArgumentCaptor.forClass(View.OnClickListener.class); verify(mPreference).setButton1OnClickListener(listenerCaptor.capture()); var listener = listenerCaptor.getValue(); assertThat(listener).isNotNull(); listener.onClick(mock(View.class)); verify(mAudioStreamsHelper).removeSource(BROADCAST_ID); verify(mPreference).setButton1Enabled(false); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_LEAVE_BUTTON_CLICK)); } @Test public void testDisplayPreference_sourceNotConnected_setConnectButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.setAudioStreamsRepositoryForTesting(mRepository); var metadataToRejoin = mock(BluetoothLeBroadcastMetadata.class); when(mRepository.getSavedMetadata(any(), anyInt())).thenReturn(metadataToRejoin); mController.displayPreference(mScreen); verify(mPreference).setButton1Enabled(true); verify(mPreference).setButton1Text(R.string.audio_streams_connect); verify(mPreference).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); verify(mPreference).setButton1OnClickListener(any(View.OnClickListener.class)); ArgumentCaptor<View.OnClickListener> listenerCaptor = ArgumentCaptor.forClass(View.OnClickListener.class); verify(mPreference).setButton1OnClickListener(listenerCaptor.capture()); var listener = listenerCaptor.getValue(); assertThat(listener).isNotNull(); listener.onClick(mock(View.class)); verify(mAudioStreamsHelper).addSource(metadataToRejoin); verify(mPreference).setButton1Enabled(false); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN), anyInt()); } @Test public void testCallback_onSourceRemoved_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceRemoved( mock(BluetoothDevice.class), /* sourceId= */ 0, /* reason= */ 0); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_connect); verify(mPreference, times(2)).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); } @Test public void testCallback_onSourceRemovedFailed_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()) .thenReturn(List.of(mBroadcastReceiveState)); when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceRemoveFailed( mock(BluetoothDevice.class), /* sourceId= */ 0, /* reason= */ 0); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_LEAVE_FAILED)); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_disconnect); verify(mPreference, times(2)) .setButton1Icon(com.android.settings.R.drawable.ic_settings_close); } @Test public void testCallback_onReceiveStateChanged_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()) .thenReturn(List.of(mBroadcastReceiveState)); when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID); BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); List<Long> bisSyncState = new ArrayList<>(); bisSyncState.add(1L); when(state.getBisSyncState()).thenReturn(bisSyncState); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onReceiveStateChanged( mock(BluetoothDevice.class), /* sourceId= */ 0, state); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED), anyInt()); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_disconnect); verify(mPreference, times(2)) .setButton1Icon(com.android.settings.R.drawable.ic_settings_close); } @Test public void testCallback_onSourceAddFailed_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceAddFailed( mock(BluetoothDevice.class), mock(BluetoothLeBroadcastMetadata.class), /* reason= */ 0); verify(mFeatureFactory.metricsFeatureProvider) .action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_OTHER), anyInt()); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_connect); verify(mPreference, times(2)).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); } @Test public void testCallback_onSourceLost_updateButton() { when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList()); mController.displayPreference(mScreen); mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 0); // Called twice, once in displayPreference, the other one in callback verify(mPreference, times(2)).setButton1Enabled(true); verify(mPreference, times(2)).setButton1Text(R.string.audio_streams_connect); verify(mPreference, times(2)).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp); } }