[Audiosharing] Increase test coverage.
Test: atest -c com.android.settings.connecteddevice.audiosharing.audiostream Flag: com.android.settingslib.flags.enable_le_audio_qr_code_private_broadcast_sharing Bug: 345686602 Change-Id: I668df463ec1c6e994d2dcaa363a20aa06f69f199
This commit is contained in:
@@ -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;
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
@@ -228,4 +230,9 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
void init(int broadcastId) {
|
||||
mBroadcastId = broadcastId;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setAudioStreamsRepositoryForTesting(AudioStreamsRepository repository) {
|
||||
mAudioStreamsRepository = repository;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
@@ -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;
|
||||
@@ -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(
|
||||
@@ -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);
|
||||
@@ -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())
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -18,28 +18,132 @@ 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.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||
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.android.settingslib.bluetooth.VolumeControlProfile;
|
||||
import com.android.settingslib.flags.Flags;
|
||||
|
||||
import org.junit.After;
|
||||
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.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(
|
||||
shadows = {
|
||||
ShadowBluetoothAdapter.class,
|
||||
ShadowBluetoothUtils.class,
|
||||
})
|
||||
public class AudioStreamConfirmDialogActivityTest {
|
||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
@Mock private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||
@Mock private LocalBluetoothLeBroadcast mBroadcast;
|
||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock private VolumeControlProfile mVolumeControl;
|
||||
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
|
||||
private AudioStreamConfirmDialogActivity mActivity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mActivity = Robolectric.buildActivity(AudioStreamConfirmDialogActivity.class).get();
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
|
||||
mShadowBluetoothAdapter.setEnabled(true);
|
||||
mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile())
|
||||
.thenReturn(mAssistant);
|
||||
when(mLocalBluetoothProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl);
|
||||
when(mBroadcast.isProfileReady()).thenReturn(true);
|
||||
when(mAssistant.isProfileReady()).thenReturn(true);
|
||||
when(mVolumeControl.isProfileReady()).thenReturn(true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowBluetoothUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isValidFragment_returnsTrue() {
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
assertThat(mActivity.isValidFragment(AudioStreamConfirmDialog.class.getName())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isValidFragment_returnsFalse() {
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
assertThat(mActivity.isValidFragment("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isToolbarEnabled_returnsFalse() {
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
assertThat(mActivity.isToolbarEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupActivity_serviceNotReady_registerCallback() {
|
||||
when(mBroadcast.isProfileReady()).thenReturn(false);
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
|
||||
verify(mLocalBluetoothProfileManager).addServiceListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupActivity_serviceNotReady_registerCallback_onServiceCallback() {
|
||||
when(mBroadcast.isProfileReady()).thenReturn(false);
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
|
||||
verify(mLocalBluetoothProfileManager).addServiceListener(any());
|
||||
|
||||
when(mBroadcast.isProfileReady()).thenReturn(true);
|
||||
mActivity.onServiceConnected();
|
||||
verify(mLocalBluetoothProfileManager).removeServiceListener(any());
|
||||
|
||||
mActivity.onServiceDisconnected();
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupActivity_serviceReady_doNothing() {
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
|
||||
verify(mLocalBluetoothProfileManager, never()).addServiceListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_unregisterCallback() {
|
||||
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||
mActivity.onStop();
|
||||
|
||||
verify(mLocalBluetoothProfileManager).removeServiceListener(any());
|
||||
}
|
||||
}
|
||||
|
@@ -16,14 +16,21 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static android.app.settings.SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_LISTEN;
|
||||
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamConfirmDialog.DEFAULT_DEVICE_NAME;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment.KEY_BROADCAST_METADATA;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
@@ -127,6 +134,8 @@ public class AudioStreamConfirmDialogTest {
|
||||
|
||||
assertThat(mDialogFragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_FEATURE_UNSUPPORTED);
|
||||
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||
|
||||
var dialog = mDialogFragment.getDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -152,6 +161,10 @@ public class AudioStreamConfirmDialogTest {
|
||||
assertThat(rightButton).isNotNull();
|
||||
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
rightButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
verify(mDialogFragment.mActivity).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -165,6 +178,8 @@ public class AudioStreamConfirmDialogTest {
|
||||
|
||||
assertThat(mDialogFragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_NO_LE_DEVICE);
|
||||
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||
|
||||
var dialog = mDialogFragment.getDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -184,11 +199,20 @@ public class AudioStreamConfirmDialogTest {
|
||||
View leftButton = dialog.findViewById(R.id.left_button);
|
||||
assertThat(leftButton).isNotNull();
|
||||
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(leftButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
leftButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
|
||||
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||
assertThat(rightButton).isNotNull();
|
||||
assertThat(rightButton.getText())
|
||||
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_button));
|
||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
rightButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
verify(mDialogFragment.mActivity, times(2)).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,6 +231,8 @@ public class AudioStreamConfirmDialogTest {
|
||||
|
||||
assertThat(mDialogFragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
||||
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||
|
||||
var dialog = mDialogFragment.getDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -231,6 +257,10 @@ public class AudioStreamConfirmDialogTest {
|
||||
assertThat(rightButton).isNotNull();
|
||||
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
rightButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
verify(mDialogFragment.mActivity).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -252,6 +282,8 @@ public class AudioStreamConfirmDialogTest {
|
||||
|
||||
assertThat(mDialogFragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
||||
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||
|
||||
var dialog = mDialogFragment.getDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
@@ -276,6 +308,10 @@ public class AudioStreamConfirmDialogTest {
|
||||
assertThat(rightButton).isNotNull();
|
||||
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
rightButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
verify(mDialogFragment.mActivity).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -283,7 +319,7 @@ public class AudioStreamConfirmDialogTest {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mBluetoothDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
|
||||
when(mBluetoothDevice.getAlias()).thenReturn("");
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(KEY_BROADCAST_METADATA, VALID_METADATA);
|
||||
@@ -296,9 +332,11 @@ public class AudioStreamConfirmDialogTest {
|
||||
shadowMainLooper().idle();
|
||||
|
||||
assertThat(mDialogFragment.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_LISTEN);
|
||||
.isEqualTo(DIALOG_AUDIO_STREAM_CONFIRM_LISTEN);
|
||||
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||
|
||||
var dialog = mDialogFragment.getDialog();
|
||||
Dialog dialog = mDialogFragment.getDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||
@@ -311,17 +349,27 @@ public class AudioStreamConfirmDialogTest {
|
||||
assertThat(subtitle1.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||
assertThat(subtitle2).isNotNull();
|
||||
var defaultName = mContext.getString(DEFAULT_DEVICE_NAME);
|
||||
assertThat(subtitle2.getText())
|
||||
.isEqualTo(
|
||||
mContext.getString(
|
||||
R.string.audio_streams_dialog_control_volume, DEVICE_NAME));
|
||||
R.string.audio_streams_dialog_control_volume, defaultName));
|
||||
View leftButton = dialog.findViewById(R.id.left_button);
|
||||
assertThat(leftButton).isNotNull();
|
||||
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(leftButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
leftButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
|
||||
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||
assertThat(rightButton).isNotNull();
|
||||
assertThat(rightButton.getText())
|
||||
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_listen));
|
||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||
|
||||
rightButton.callOnClick();
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
verify(mDialogFragment.mActivity, times(2)).finish();
|
||||
}
|
||||
}
|
||||
|
@@ -16,22 +16,48 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamDetailsFragment.BROADCAST_ID_ARG;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamDetailsFragment.BROADCAST_NAME_ARG;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
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 AudioStreamDetailsFragmentTest {
|
||||
private AudioStreamDetailsFragment mFragment;
|
||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
private static final String BROADCAST_NAME = "name";
|
||||
private static final int BROADCAST_ID = 1;
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock private AudioStreamHeaderController mHeaderController;
|
||||
@Mock private AudioStreamButtonController mButtonController;
|
||||
private TestFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFragment = new AudioStreamDetailsFragment();
|
||||
mFragment = spy(new TestFragment());
|
||||
doReturn(mHeaderController).when(mFragment).use(AudioStreamHeaderController.class);
|
||||
doReturn(mButtonController).when(mFragment).use(AudioStreamButtonController.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -44,4 +70,29 @@ public class AudioStreamDetailsFragmentTest {
|
||||
public void getLogTag_returnsCorrectTag() {
|
||||
assertThat(mFragment.getLogTag()).isEqualTo(AudioStreamDetailsFragment.TAG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_returnsCorrectEnum() {
|
||||
assertThat(mFragment.getMetricsCategory()).isEqualTo(SettingsEnums.AUDIO_STREAM_DETAIL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttach_getArguments() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(BROADCAST_NAME_ARG, BROADCAST_NAME);
|
||||
bundle.putInt(BROADCAST_ID_ARG, BROADCAST_ID);
|
||||
mFragment.setArguments(bundle);
|
||||
|
||||
mFragment.onAttach(mContext);
|
||||
|
||||
verify(mButtonController).init(BROADCAST_ID);
|
||||
verify(mHeaderController).init(mFragment, BROADCAST_NAME, BROADCAST_ID);
|
||||
}
|
||||
|
||||
public static class TestFragment extends AudioStreamDetailsFragment {
|
||||
@Override
|
||||
protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
|
||||
return super.use(clazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,12 +19,20 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamHeaderController.AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamHeaderController.AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
@@ -32,6 +40,8 @@ import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadow
|
||||
import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowEntityHeaderController;
|
||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -45,8 +55,10 @@ 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(
|
||||
@@ -65,15 +77,21 @@ public class AudioStreamHeaderControllerTest {
|
||||
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
||||
@Mock private PreferenceScreen mScreen;
|
||||
@Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
|
||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock private AudioStreamDetailsFragment mFragment;
|
||||
@Mock private LayoutPreference mPreference;
|
||||
@Mock private EntityHeaderController mHeaderController;
|
||||
private Lifecycle mLifecycle;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private AudioStreamHeaderController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowEntityHeaderController.setUseMock(mHeaderController);
|
||||
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
||||
when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mAssistant);
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
mController = new AudioStreamHeaderController(mContext, KEY);
|
||||
mController.init(mFragment, BROADCAST_NAME, BROADCAST_ID);
|
||||
when(mScreen.findPreference(KEY)).thenReturn(mPreference);
|
||||
@@ -87,6 +105,40 @@ public class AudioStreamHeaderControllerTest {
|
||||
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 AudioStreamHeaderController(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 AudioStreamHeaderController(mContext, KEY);
|
||||
mController.onStop(mLifecycleOwner);
|
||||
verify(mAssistant, never())
|
||||
.unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourceConnected_setSummary() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||
@@ -96,9 +148,11 @@ public class AudioStreamHeaderControllerTest {
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
||||
verify(mHeaderController).setIcon(any(Drawable.class));
|
||||
verify(mHeaderController)
|
||||
.setSummary(mContext.getString(AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY));
|
||||
verify(mHeaderController).done(true);
|
||||
verify(mScreen).addPreference(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,7 +162,54 @@ public class AudioStreamHeaderControllerTest {
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
||||
verify(mHeaderController).setIcon(any(Drawable.class));
|
||||
verify(mHeaderController).setSummary(AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY);
|
||||
verify(mHeaderController).done(true);
|
||||
verify(mScreen).addPreference(any());
|
||||
}
|
||||
|
||||
@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(mHeaderController, times(2)).setSummary(AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY);
|
||||
verify(mHeaderController, times(2)).done(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceLost_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
||||
|
||||
// Called twice, once in displayPreference, the other one in callback
|
||||
verify(mHeaderController, times(2)).setSummary(AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY);
|
||||
verify(mHeaderController, times(2)).done(true);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
// Called twice, once in displayPreference, the other one in callback
|
||||
verify(mHeaderController, times(2))
|
||||
.setSummary(mContext.getString(AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY));
|
||||
verify(mHeaderController, times(2)).done(true);
|
||||
}
|
||||
}
|
||||
|
@@ -22,18 +22,25 @@ import static com.android.settings.connecteddevice.audiosharing.audiostreams.Aud
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -53,12 +60,14 @@ public class AudioStreamsDashboardFragmentTest {
|
||||
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private AudioStreamsProgressCategoryController mController;
|
||||
private TestFragment mTestFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mTestFragment = spy(new TestFragment());
|
||||
doReturn(mContext).when(mTestFragment).getContext();
|
||||
mController = spy(new AudioStreamsProgressCategoryController(mContext, "key"));
|
||||
@@ -114,6 +123,28 @@ public class AudioStreamsDashboardFragmentTest {
|
||||
mTestFragment.onActivityResult(
|
||||
REQUEST_SCAN_BT_BROADCAST_QR_CODE, Activity.RESULT_OK, intent);
|
||||
verify(mController).setSourceFromQrCode(any(), any());
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(
|
||||
any(),
|
||||
eq(SettingsEnums.ACTION_AUDIO_STREAM_QR_CODE_SCAN_SUCCEED),
|
||||
anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAttach_hasArgument() {
|
||||
BluetoothLeBroadcastMetadata data = mock(BluetoothLeBroadcastMetadata.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_BROADCAST_METADATA, data);
|
||||
mTestFragment.setArguments(bundle);
|
||||
|
||||
mTestFragment.onAttach(mContext);
|
||||
|
||||
verify(mController).setSourceFromQrCode(eq(data), any());
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(
|
||||
any(),
|
||||
eq(SettingsEnums.ACTION_AUDIO_STREAM_QR_CODE_SCAN_SUCCEED),
|
||||
anyInt());
|
||||
}
|
||||
|
||||
public static class TestFragment extends AudioStreamsDashboardFragment {
|
||||
|
@@ -73,7 +73,7 @@ public class AudioStreamsDialogFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowDialog() {
|
||||
public void testShowDialog_dismissAll() {
|
||||
FragmentController.setupFragment(mFragment);
|
||||
AudioStreamsDialogFragment.show(mFragment, mDialogBuilder, SettingsEnums.PAGE_UNKNOWN);
|
||||
ShadowLooper.idleMainLooper();
|
||||
@@ -81,5 +81,8 @@ public class AudioStreamsDialogFragmentTest {
|
||||
var dialog = ShadowAlertDialog.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
assertThat(dialog.isShowing()).isTrue();
|
||||
|
||||
AudioStreamsDialogFragment.dismissAll(mFragment);
|
||||
assertThat(dialog.isShowing()).isFalse();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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.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.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
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;
|
||||
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;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(
|
||||
shadows = {
|
||||
ShadowThreadUtils.class,
|
||||
})
|
||||
public class AudioStreamsHelperTest {
|
||||
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
private static final int GROUP_ID = 1;
|
||||
private static final int BROADCAST_ID_1 = 1;
|
||||
private static final int BROADCAST_ID_2 = 2;
|
||||
private static final String BROADCAST_NAME = "name";
|
||||
private final Context mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
@Mock private LocalBluetoothManager mLocalBluetoothManager;
|
||||
@Mock private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
|
||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||
@Mock private CachedBluetoothDeviceManager mDeviceManager;
|
||||
@Mock private BluetoothLeBroadcastMetadata mMetadata;
|
||||
@Mock private CachedBluetoothDevice mCachedDevice;
|
||||
@Mock private BluetoothDevice mDevice;
|
||||
private AudioStreamsHelper mHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile())
|
||||
.thenReturn(mAssistant);
|
||||
mHelper = spy(new AudioStreamsHelper(mLocalBluetoothManager));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addSource_noDevice_doNothing() {
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
mHelper.addSource(mMetadata);
|
||||
|
||||
verify(mAssistant, never()).addSource(any(), any(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addSource_hasDevice() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
|
||||
mHelper.addSource(mMetadata);
|
||||
|
||||
verify(mAssistant).addSource(eq(mDevice), eq(mMetadata), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeSource_noDevice_doNothing() {
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
mHelper.removeSource(BROADCAST_ID_1);
|
||||
|
||||
verify(mAssistant, never()).removeSource(any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeSource_noConnectedSource_doNothing() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(source));
|
||||
|
||||
mHelper.removeSource(BROADCAST_ID_1);
|
||||
|
||||
verify(mAssistant, never()).removeSource(any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeSource_hasConnectedSource() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(source));
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
when(source.getBisSyncState()).thenReturn(bisSyncState);
|
||||
|
||||
mHelper.removeSource(BROADCAST_ID_2);
|
||||
|
||||
verify(mAssistant).removeSource(eq(mDevice), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeSource_memberHasConnectedSource() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
var memberDevice = mock(BluetoothDevice.class);
|
||||
devices.add(mDevice);
|
||||
devices.add(memberDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
var memberCachedDevice = mock(CachedBluetoothDevice.class);
|
||||
when(memberCachedDevice.getDevice()).thenReturn(memberDevice);
|
||||
when(mCachedDevice.getMemberDevice()).thenReturn(ImmutableSet.of(memberCachedDevice));
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
when(mAssistant.getAllSources(mDevice)).thenReturn(ImmutableList.of());
|
||||
when(mAssistant.getAllSources(memberDevice)).thenReturn(ImmutableList.of(source));
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
when(source.getBisSyncState()).thenReturn(bisSyncState);
|
||||
|
||||
mHelper.removeSource(BROADCAST_ID_2);
|
||||
|
||||
verify(mAssistant).removeSource(eq(memberDevice), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllConnectedSources_noAssistant() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(null);
|
||||
mHelper = new AudioStreamsHelper(mLocalBluetoothManager);
|
||||
|
||||
assertThat(mHelper.getAllConnectedSources()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllConnectedSources_returnSource() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(source));
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
when(source.getBisSyncState()).thenReturn(bisSyncState);
|
||||
|
||||
var list = mHelper.getAllConnectedSources();
|
||||
assertThat(list).isNotEmpty();
|
||||
assertThat(list.get(0)).isEqualTo(source);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startMediaService_noDevice_doNothing() {
|
||||
mHelper.startMediaService(mContext, BROADCAST_ID_1, BROADCAST_NAME);
|
||||
|
||||
verify(mContext, never()).startService(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startMediaService_hasDevice() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(source));
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
when(source.getBisSyncState()).thenReturn(bisSyncState);
|
||||
|
||||
mHelper.startMediaService(mContext, BROADCAST_ID_1, BROADCAST_NAME);
|
||||
|
||||
verify(mContext).startService(any());
|
||||
}
|
||||
}
|
@@ -167,6 +167,25 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
verify(mPreference).setProgress(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowToast_noError() {
|
||||
mController.showToast(BROADCAST_NAME_1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStop_unregister() {
|
||||
mController.onStop(mLifecycleOwner);
|
||||
|
||||
verify(mBluetoothEventManager).unregisterCallback(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFragment_returnFragment() {
|
||||
mController.setFragment(mFragment);
|
||||
|
||||
assertThat(mController.getFragment()).isEqualTo(mFragment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStart_initNoDevice_showDialog() {
|
||||
when(mLeBroadcastAssistant.isSearchInProgress()).thenReturn(true);
|
||||
@@ -244,6 +263,25 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
verify(mController, never()).moveToState(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStart_initHasDevice_scanningInProgress() {
|
||||
// Setup a device
|
||||
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(mDevice);
|
||||
when(mLeBroadcastAssistant.isSearchInProgress()).thenReturn(true);
|
||||
|
||||
mController.onStart(mLifecycleOwner);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
verify(mLeBroadcastAssistant).registerServiceCallBack(any(), any());
|
||||
verify(mLeBroadcastAssistant).stopSearchingForSources();
|
||||
verify(mLeBroadcastAssistant).startSearchingForSources(any());
|
||||
|
||||
var dialog = ShadowAlertDialog.getLatestAlertDialog();
|
||||
assertThat(dialog).isNull();
|
||||
|
||||
verify(mController, never()).moveToState(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStart_handleSourceFromQrCode() {
|
||||
// Setup a device
|
||||
@@ -382,6 +420,49 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
assertThat(state.getValue()).isEqualTo(SYNCED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleSourceAddRequest_updateMetadataAndState() {
|
||||
// Setup a device
|
||||
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(mDevice);
|
||||
|
||||
var metadata =
|
||||
BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(VALID_METADATA);
|
||||
assertThat(metadata).isNotNull();
|
||||
var metadataWithNoCode =
|
||||
new BluetoothLeBroadcastMetadata.Builder(metadata)
|
||||
.setBroadcastId(NEWLY_FOUND_BROADCAST_ID)
|
||||
.setBroadcastName(BROADCAST_NAME_1)
|
||||
.build();
|
||||
// A new source is found
|
||||
mController.handleSourceFound(metadataWithNoCode);
|
||||
|
||||
ArgumentCaptor<AudioStreamPreference> preferenceCaptor =
|
||||
ArgumentCaptor.forClass(AudioStreamPreference.class);
|
||||
ArgumentCaptor<AudioStreamsProgressCategoryController.AudioStreamState> stateCaptor =
|
||||
ArgumentCaptor.forClass(
|
||||
AudioStreamsProgressCategoryController.AudioStreamState.class);
|
||||
|
||||
// moving state to SYNCED
|
||||
verify(mController).moveToState(preferenceCaptor.capture(), stateCaptor.capture());
|
||||
var preference = preferenceCaptor.getValue();
|
||||
var state = stateCaptor.getValue();
|
||||
|
||||
assertThat(preference).isNotNull();
|
||||
assertThat(preference.getAudioStreamBroadcastId()).isEqualTo(NEWLY_FOUND_BROADCAST_ID);
|
||||
assertThat(state).isEqualTo(SYNCED);
|
||||
|
||||
var updatedMetadata =
|
||||
new BluetoothLeBroadcastMetadata.Builder(metadataWithNoCode)
|
||||
.setBroadcastCode(BROADCAST_CODE)
|
||||
.build();
|
||||
mController.handleSourceAddRequest(preference, updatedMetadata);
|
||||
// state updated to ADD_SOURCE_WAIT_FOR_RESPONSE
|
||||
assertThat(preference.getAudioStreamBroadcastId()).isEqualTo(NEWLY_FOUND_BROADCAST_ID);
|
||||
assertThat(preference.getAudioStreamMetadata().getBroadcastCode())
|
||||
.isEqualTo(BROADCAST_CODE);
|
||||
assertThat(preference.getAudioStreamState()).isEqualTo(ADD_SOURCE_WAIT_FOR_RESPONSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleSourceFound_sameIdWithSourceFromQrCode_updateMetadataAndState() {
|
||||
// Setup a device
|
||||
@@ -518,6 +599,42 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
.isEqualTo(NEWLY_FOUND_BROADCAST_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleSourceLost_sourceConnected_doNothing() {
|
||||
// Setup a device
|
||||
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(mDevice);
|
||||
|
||||
// Setup mPreference so it's not null
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
// A new source found
|
||||
when(mMetadata.getBroadcastId()).thenReturn(NEWLY_FOUND_BROADCAST_ID);
|
||||
mController.handleSourceFound(mMetadata);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
// A new source found is lost, but the source is still connected
|
||||
BluetoothLeBroadcastReceiveState connected = createConnectedMock(NEWLY_FOUND_BROADCAST_ID);
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(ImmutableList.of(connected));
|
||||
mController.handleSourceLost(NEWLY_FOUND_BROADCAST_ID);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
ArgumentCaptor<AudioStreamPreference> preferenceToAdd =
|
||||
ArgumentCaptor.forClass(AudioStreamPreference.class);
|
||||
ArgumentCaptor<AudioStreamsProgressCategoryController.AudioStreamState> state =
|
||||
ArgumentCaptor.forClass(
|
||||
AudioStreamsProgressCategoryController.AudioStreamState.class);
|
||||
|
||||
// Verify a new preference is created with state SYNCED.
|
||||
verify(mController).moveToState(preferenceToAdd.capture(), state.capture());
|
||||
assertThat(preferenceToAdd.getValue()).isNotNull();
|
||||
assertThat(preferenceToAdd.getValue().getAudioStreamBroadcastId())
|
||||
.isEqualTo(NEWLY_FOUND_BROADCAST_ID);
|
||||
assertThat(state.getValue()).isEqualTo(SYNCED);
|
||||
|
||||
// No preference is removed.
|
||||
verify(mPreference, never()).removePreference(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleSourceRemoved_removed() {
|
||||
// Setup a device
|
||||
|
@@ -53,6 +53,8 @@ public class AudioStreamsProgressCategoryPreferenceTest {
|
||||
|
||||
@Test
|
||||
public void addAudioStreamPreference_singlePreference() {
|
||||
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext, null));
|
||||
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||
mPreference.addAudioStreamPreference(first, (p1, p2) -> 0);
|
||||
|
||||
@@ -62,6 +64,8 @@ public class AudioStreamsProgressCategoryPreferenceTest {
|
||||
|
||||
@Test
|
||||
public void addAudioStreamPreference_multiPreference_sorted() {
|
||||
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext, null, 0));
|
||||
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
Comparator<AudioStreamPreference> c =
|
||||
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
||||
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||
@@ -78,6 +82,8 @@ public class AudioStreamsProgressCategoryPreferenceTest {
|
||||
|
||||
@Test
|
||||
public void removeAudioStreamPreferences_shouldBeEmpty() {
|
||||
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext, null, 0, 0));
|
||||
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
Comparator<AudioStreamPreference> c =
|
||||
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
||||
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||
|
@@ -97,6 +97,22 @@ public class AudioStreamsQrCodeFragmentTest {
|
||||
assertThat(mFragment.getMetricsCategory()).isEqualTo(SettingsEnums.AUDIO_STREAM_QR_CODE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateView_noProfile_noQrCode() {
|
||||
when(mBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
|
||||
FragmentController.setupFragment(
|
||||
mFragment, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
|
||||
View view = mFragment.getView();
|
||||
|
||||
assertThat(view).isNotNull();
|
||||
ImageView qrCodeView = view.findViewById(R.id.qrcode_view);
|
||||
TextView passwordView = view.requireViewById(R.id.password);
|
||||
assertThat(qrCodeView).isNotNull();
|
||||
assertThat(qrCodeView.getDrawable()).isNull();
|
||||
assertThat(passwordView).isNotNull();
|
||||
assertThat(passwordView.getText().toString()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreateView_noMetadata_noQrCode() {
|
||||
List<BluetoothLeBroadcastMetadata> list = new ArrayList<>();
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows;
|
||||
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -69,4 +70,16 @@ public class ShadowAudioStreamsHelper {
|
||||
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
||||
return sMockHelper.getLeBroadcastAssistant();
|
||||
}
|
||||
|
||||
/** Removes sources from LE broadcasts associated for all active sinks based on broadcast Id. */
|
||||
@Implementation
|
||||
public void removeSource(int broadcastId) {
|
||||
sMockHelper.removeSource(broadcastId);
|
||||
}
|
||||
|
||||
/** Adds the specified LE broadcast source to all active sinks. */
|
||||
@Implementation
|
||||
public void addSource(BluetoothLeBroadcastMetadata source) {
|
||||
sMockHelper.addSource(source);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user