[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.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
@@ -48,7 +49,9 @@ public class AudioStreamButtonController extends BasePreferenceController
|
|||||||
private static final String TAG = "AudioStreamButtonController";
|
private static final String TAG = "AudioStreamButtonController";
|
||||||
private static final String KEY = "audio_stream_button";
|
private static final String KEY = "audio_stream_button";
|
||||||
private static final int SOURCE_ORIGIN_REPOSITORY = SourceOriginForLogging.REPOSITORY.ordinal();
|
private static final int SOURCE_ORIGIN_REPOSITORY = SourceOriginForLogging.REPOSITORY.ordinal();
|
||||||
private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
|
||||||
|
@VisibleForTesting
|
||||||
|
final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
||||||
new AudioStreamsBroadcastAssistantCallback() {
|
new AudioStreamsBroadcastAssistantCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {
|
public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {
|
||||||
@@ -97,8 +100,7 @@ public class AudioStreamButtonController extends BasePreferenceController
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final AudioStreamsRepository mAudioStreamsRepository =
|
private AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance();
|
||||||
AudioStreamsRepository.getInstance();
|
|
||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
private final AudioStreamsHelper mAudioStreamsHelper;
|
private final AudioStreamsHelper mAudioStreamsHelper;
|
||||||
private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||||
@@ -228,4 +230,9 @@ public class AudioStreamButtonController extends BasePreferenceController
|
|||||||
void init(int broadcastId) {
|
void init(int broadcastId) {
|
||||||
mBroadcastId = broadcastId;
|
mBroadcastId = broadcastId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void setAudioStreamsRepositoryForTesting(AudioStreamsRepository repository) {
|
||||||
|
mAudioStreamsRepository = repository;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.bluetooth.Utils;
|
import com.android.settings.bluetooth.Utils;
|
||||||
@@ -43,9 +44,12 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
|||||||
|
|
||||||
public class AudioStreamConfirmDialog extends InstrumentedDialogFragment {
|
public class AudioStreamConfirmDialog extends InstrumentedDialogFragment {
|
||||||
private static final String TAG = "AudioStreamConfirmDialog";
|
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;
|
private Context mContext;
|
||||||
@Nullable private Activity mActivity;
|
@VisibleForTesting @Nullable Activity mActivity;
|
||||||
@Nullable private BluetoothLeBroadcastMetadata mBroadcastMetadata;
|
@Nullable private BluetoothLeBroadcastMetadata mBroadcastMetadata;
|
||||||
@Nullable private BluetoothDevice mConnectedDevice;
|
@Nullable private BluetoothDevice mConnectedDevice;
|
||||||
private int mAudioStreamConfirmDialogId = SettingsEnums.PAGE_UNKNOWN;
|
private int mAudioStreamConfirmDialogId = SettingsEnums.PAGE_UNKNOWN;
|
||||||
|
@@ -54,7 +54,9 @@ public class AudioStreamHeaderController extends BasePreferenceController
|
|||||||
private final Executor mExecutor;
|
private final Executor mExecutor;
|
||||||
private final AudioStreamsHelper mAudioStreamsHelper;
|
private final AudioStreamsHelper mAudioStreamsHelper;
|
||||||
@Nullable private final LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
@Nullable private final LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||||
private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
|
||||||
|
@VisibleForTesting
|
||||||
|
final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
||||||
new AudioStreamsBroadcastAssistantCallback() {
|
new AudioStreamsBroadcastAssistantCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {
|
public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {
|
||||||
|
@@ -23,7 +23,6 @@ import android.app.settings.SettingsEnums;
|
|||||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -63,11 +62,6 @@ public class AudioStreamsDashboardFragment extends DashboardFragment {
|
|||||||
return R.xml.bluetooth_le_audio_streams;
|
return R.xml.bluetooth_le_audio_streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
@@ -91,11 +85,6 @@ public class AudioStreamsDashboardFragment extends DashboardFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
@@ -16,22 +16,36 @@
|
|||||||
|
|
||||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
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.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
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.verify;
|
||||||
import static org.mockito.Mockito.when;
|
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.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper;
|
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.settings.testutils.shadow.ShadowThreadUtils;
|
||||||
|
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.widget.ActionButtonsPreference;
|
import com.android.settingslib.widget.ActionButtonsPreference;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -39,14 +53,17 @@ import org.junit.Before;
|
|||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnit;
|
||||||
import org.mockito.junit.MockitoRule;
|
import org.mockito.junit.MockitoRule;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(
|
@Config(
|
||||||
@@ -63,14 +80,23 @@ public class AudioStreamButtonControllerTest {
|
|||||||
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
||||||
@Mock private PreferenceScreen mScreen;
|
@Mock private PreferenceScreen mScreen;
|
||||||
@Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
|
@Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
|
||||||
|
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||||
|
@Mock private AudioStreamsRepository mRepository;
|
||||||
@Mock private ActionButtonsPreference mPreference;
|
@Mock private ActionButtonsPreference mPreference;
|
||||||
|
private Lifecycle mLifecycle;
|
||||||
|
private LifecycleOwner mLifecycleOwner;
|
||||||
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
private AudioStreamButtonController mController;
|
private AudioStreamButtonController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
||||||
|
when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mAssistant);
|
||||||
|
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
mController = new AudioStreamButtonController(mContext, KEY);
|
mController = new AudioStreamButtonController(mContext, KEY);
|
||||||
mController.init(BROADCAST_ID);
|
mController.init(BROADCAST_ID);
|
||||||
|
mLifecycleOwner = () -> mLifecycle;
|
||||||
|
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||||
when(mScreen.findPreference(KEY)).thenReturn(mPreference);
|
when(mScreen.findPreference(KEY)).thenReturn(mPreference);
|
||||||
when(mPreference.getContext()).thenReturn(mContext);
|
when(mPreference.getContext()).thenReturn(mContext);
|
||||||
when(mPreference.setButton1Text(anyInt())).thenReturn(mPreference);
|
when(mPreference.setButton1Text(anyInt())).thenReturn(mPreference);
|
||||||
@@ -85,6 +111,40 @@ public class AudioStreamButtonControllerTest {
|
|||||||
ShadowAudioStreamsHelper.reset();
|
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
|
@Test
|
||||||
public void testDisplayPreference_sourceConnected_setDisconnectButton() {
|
public void testDisplayPreference_sourceConnected_setDisconnectButton() {
|
||||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||||
@@ -96,18 +156,133 @@ public class AudioStreamButtonControllerTest {
|
|||||||
verify(mPreference).setButton1Enabled(true);
|
verify(mPreference).setButton1Enabled(true);
|
||||||
verify(mPreference).setButton1Text(R.string.audio_streams_disconnect);
|
verify(mPreference).setButton1Text(R.string.audio_streams_disconnect);
|
||||||
verify(mPreference).setButton1Icon(com.android.settings.R.drawable.ic_settings_close);
|
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
|
@Test
|
||||||
public void testDisplayPreference_sourceNotConnected_setConnectButton() {
|
public void testDisplayPreference_sourceNotConnected_setConnectButton() {
|
||||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||||
|
mController.setAudioStreamsRepositoryForTesting(mRepository);
|
||||||
|
var metadataToRejoin = mock(BluetoothLeBroadcastMetadata.class);
|
||||||
|
when(mRepository.getSavedMetadata(any(), anyInt())).thenReturn(metadataToRejoin);
|
||||||
|
|
||||||
mController.displayPreference(mScreen);
|
mController.displayPreference(mScreen);
|
||||||
|
|
||||||
verify(mPreference).setButton1Enabled(true);
|
verify(mPreference).setButton1Enabled(true);
|
||||||
verify(mPreference).setButton1Text(R.string.audio_streams_connect);
|
verify(mPreference).setButton1Text(R.string.audio_streams_connect);
|
||||||
verify(mPreference).setButton1Icon(com.android.settings.R.drawable.ic_add_24dp);
|
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 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.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
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.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadow.api.Shadow;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(
|
||||||
|
shadows = {
|
||||||
|
ShadowBluetoothAdapter.class,
|
||||||
|
ShadowBluetoothUtils.class,
|
||||||
|
})
|
||||||
public class AudioStreamConfirmDialogActivityTest {
|
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;
|
private AudioStreamConfirmDialogActivity mActivity;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
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
|
@Test
|
||||||
public void isValidFragment_returnsTrue() {
|
public void isValidFragment_returnsTrue() {
|
||||||
|
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||||
assertThat(mActivity.isValidFragment(AudioStreamConfirmDialog.class.getName())).isTrue();
|
assertThat(mActivity.isValidFragment(AudioStreamConfirmDialog.class.getName())).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isValidFragment_returnsFalse() {
|
public void isValidFragment_returnsFalse() {
|
||||||
|
mActivity = Robolectric.setupActivity(AudioStreamConfirmDialogActivity.class);
|
||||||
assertThat(mActivity.isValidFragment("")).isFalse();
|
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;
|
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.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsDashboardFragment.KEY_BROADCAST_METADATA;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
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.mockito.Mockito.when;
|
||||||
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
|
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
@@ -127,6 +134,8 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
|
|
||||||
assertThat(mDialogFragment.getMetricsCategory())
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_FEATURE_UNSUPPORTED);
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_FEATURE_UNSUPPORTED);
|
||||||
|
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||||
|
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||||
|
|
||||||
var dialog = mDialogFragment.getDialog();
|
var dialog = mDialogFragment.getDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -152,6 +161,10 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
assertThat(rightButton).isNotNull();
|
assertThat(rightButton).isNotNull();
|
||||||
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
|
||||||
|
rightButton.callOnClick();
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
verify(mDialogFragment.mActivity).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -165,6 +178,8 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
|
|
||||||
assertThat(mDialogFragment.getMetricsCategory())
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_NO_LE_DEVICE);
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_NO_LE_DEVICE);
|
||||||
|
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||||
|
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||||
|
|
||||||
var dialog = mDialogFragment.getDialog();
|
var dialog = mDialogFragment.getDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -184,11 +199,20 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
View leftButton = dialog.findViewById(R.id.left_button);
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
assertThat(leftButton).isNotNull();
|
assertThat(leftButton).isNotNull();
|
||||||
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(leftButton.hasOnClickListeners()).isTrue();
|
||||||
|
|
||||||
|
leftButton.callOnClick();
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
|
||||||
Button rightButton = dialog.findViewById(R.id.right_button);
|
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||||
assertThat(rightButton).isNotNull();
|
assertThat(rightButton).isNotNull();
|
||||||
assertThat(rightButton.getText())
|
assertThat(rightButton.getText())
|
||||||
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_button));
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_no_le_device_button));
|
||||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
|
||||||
|
rightButton.callOnClick();
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
verify(mDialogFragment.mActivity, times(2)).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -207,6 +231,8 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
|
|
||||||
assertThat(mDialogFragment.getMetricsCategory())
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
||||||
|
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||||
|
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||||
|
|
||||||
var dialog = mDialogFragment.getDialog();
|
var dialog = mDialogFragment.getDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -231,6 +257,10 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
assertThat(rightButton).isNotNull();
|
assertThat(rightButton).isNotNull();
|
||||||
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
|
||||||
|
rightButton.callOnClick();
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
verify(mDialogFragment.mActivity).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -252,6 +282,8 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
|
|
||||||
assertThat(mDialogFragment.getMetricsCategory())
|
assertThat(mDialogFragment.getMetricsCategory())
|
||||||
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
.isEqualTo(SettingsEnums.DIALOG_AUDIO_STREAM_CONFIRM_DATA_ERROR);
|
||||||
|
assertThat(mDialogFragment.mActivity).isNotNull();
|
||||||
|
mDialogFragment.mActivity = spy(mDialogFragment.mActivity);
|
||||||
|
|
||||||
var dialog = mDialogFragment.getDialog();
|
var dialog = mDialogFragment.getDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
@@ -276,6 +308,10 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
assertThat(rightButton).isNotNull();
|
assertThat(rightButton).isNotNull();
|
||||||
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(rightButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
||||||
|
|
||||||
|
rightButton.callOnClick();
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
verify(mDialogFragment.mActivity).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -283,7 +319,7 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
List<BluetoothDevice> devices = new ArrayList<>();
|
List<BluetoothDevice> devices = new ArrayList<>();
|
||||||
devices.add(mBluetoothDevice);
|
devices.add(mBluetoothDevice);
|
||||||
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
when(mAssistant.getDevicesMatchingConnectionStates(any())).thenReturn(devices);
|
||||||
when(mBluetoothDevice.getAlias()).thenReturn(DEVICE_NAME);
|
when(mBluetoothDevice.getAlias()).thenReturn("");
|
||||||
|
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra(KEY_BROADCAST_METADATA, VALID_METADATA);
|
intent.putExtra(KEY_BROADCAST_METADATA, VALID_METADATA);
|
||||||
@@ -296,9 +332,11 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
shadowMainLooper().idle();
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
assertThat(mDialogFragment.getMetricsCategory())
|
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).isNotNull();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
assertThat(dialog.isShowing()).isTrue();
|
||||||
TextView title = dialog.findViewById(R.id.dialog_title);
|
TextView title = dialog.findViewById(R.id.dialog_title);
|
||||||
@@ -311,17 +349,27 @@ public class AudioStreamConfirmDialogTest {
|
|||||||
assertThat(subtitle1.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(subtitle1.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
TextView subtitle2 = dialog.findViewById(R.id.dialog_subtitle_2);
|
||||||
assertThat(subtitle2).isNotNull();
|
assertThat(subtitle2).isNotNull();
|
||||||
|
var defaultName = mContext.getString(DEFAULT_DEVICE_NAME);
|
||||||
assertThat(subtitle2.getText())
|
assertThat(subtitle2.getText())
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
mContext.getString(
|
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);
|
View leftButton = dialog.findViewById(R.id.left_button);
|
||||||
assertThat(leftButton).isNotNull();
|
assertThat(leftButton).isNotNull();
|
||||||
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(leftButton.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(leftButton.hasOnClickListeners()).isTrue();
|
||||||
|
|
||||||
|
leftButton.callOnClick();
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
|
||||||
Button rightButton = dialog.findViewById(R.id.right_button);
|
Button rightButton = dialog.findViewById(R.id.right_button);
|
||||||
assertThat(rightButton).isNotNull();
|
assertThat(rightButton).isNotNull();
|
||||||
assertThat(rightButton.getText())
|
assertThat(rightButton.getText())
|
||||||
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_listen));
|
.isEqualTo(mContext.getString(R.string.audio_streams_dialog_listen));
|
||||||
assertThat(rightButton.hasOnClickListeners()).isTrue();
|
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;
|
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 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.settings.R;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
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.RobolectricTestRunner;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class AudioStreamDetailsFragmentTest {
|
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
|
@Before
|
||||||
public void setUp() {
|
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
|
@Test
|
||||||
@@ -44,4 +70,29 @@ public class AudioStreamDetailsFragmentTest {
|
|||||||
public void getLogTag_returnsCorrectTag() {
|
public void getLogTag_returnsCorrectTag() {
|
||||||
assertThat(mFragment.getLogTag()).isEqualTo(AudioStreamDetailsFragment.TAG);
|
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_LISTENING_NOW_SUMMARY;
|
||||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamHeaderController.AUDIO_STREAM_HEADER_NOT_LISTENING_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.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
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.connecteddevice.audiosharing.audiostreams.testshadows.ShadowEntityHeaderController;
|
||||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
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 com.android.settingslib.widget.LayoutPreference;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -45,8 +55,10 @@ import org.mockito.junit.MockitoRule;
|
|||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(
|
@Config(
|
||||||
@@ -65,15 +77,21 @@ public class AudioStreamHeaderControllerTest {
|
|||||||
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
@Mock private AudioStreamsHelper mAudioStreamsHelper;
|
||||||
@Mock private PreferenceScreen mScreen;
|
@Mock private PreferenceScreen mScreen;
|
||||||
@Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
|
@Mock private BluetoothLeBroadcastReceiveState mBroadcastReceiveState;
|
||||||
|
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||||
@Mock private AudioStreamDetailsFragment mFragment;
|
@Mock private AudioStreamDetailsFragment mFragment;
|
||||||
@Mock private LayoutPreference mPreference;
|
@Mock private LayoutPreference mPreference;
|
||||||
@Mock private EntityHeaderController mHeaderController;
|
@Mock private EntityHeaderController mHeaderController;
|
||||||
|
private Lifecycle mLifecycle;
|
||||||
|
private LifecycleOwner mLifecycleOwner;
|
||||||
private AudioStreamHeaderController mController;
|
private AudioStreamHeaderController mController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
ShadowEntityHeaderController.setUseMock(mHeaderController);
|
ShadowEntityHeaderController.setUseMock(mHeaderController);
|
||||||
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper);
|
||||||
|
when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mAssistant);
|
||||||
|
mLifecycleOwner = () -> mLifecycle;
|
||||||
|
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||||
mController = new AudioStreamHeaderController(mContext, KEY);
|
mController = new AudioStreamHeaderController(mContext, KEY);
|
||||||
mController.init(mFragment, BROADCAST_NAME, BROADCAST_ID);
|
mController.init(mFragment, BROADCAST_NAME, BROADCAST_ID);
|
||||||
when(mScreen.findPreference(KEY)).thenReturn(mPreference);
|
when(mScreen.findPreference(KEY)).thenReturn(mPreference);
|
||||||
@@ -87,6 +105,40 @@ public class AudioStreamHeaderControllerTest {
|
|||||||
ShadowAudioStreamsHelper.reset();
|
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
|
@Test
|
||||||
public void testDisplayPreference_sourceConnected_setSummary() {
|
public void testDisplayPreference_sourceConnected_setSummary() {
|
||||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||||
@@ -96,9 +148,11 @@ public class AudioStreamHeaderControllerTest {
|
|||||||
mController.displayPreference(mScreen);
|
mController.displayPreference(mScreen);
|
||||||
|
|
||||||
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
||||||
|
verify(mHeaderController).setIcon(any(Drawable.class));
|
||||||
verify(mHeaderController)
|
verify(mHeaderController)
|
||||||
.setSummary(mContext.getString(AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY));
|
.setSummary(mContext.getString(AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY));
|
||||||
verify(mHeaderController).done(true);
|
verify(mHeaderController).done(true);
|
||||||
|
verify(mScreen).addPreference(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -108,7 +162,54 @@ public class AudioStreamHeaderControllerTest {
|
|||||||
mController.displayPreference(mScreen);
|
mController.displayPreference(mScreen);
|
||||||
|
|
||||||
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
||||||
|
verify(mHeaderController).setIcon(any(Drawable.class));
|
||||||
verify(mHeaderController).setSummary(AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY);
|
verify(mHeaderController).setSummary(AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY);
|
||||||
verify(mHeaderController).done(true);
|
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 com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
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.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.settings.SettingsEnums;
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import org.junit.Before;
|
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=;;";
|
+ "MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;";
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
private AudioStreamsProgressCategoryController mController;
|
private AudioStreamsProgressCategoryController mController;
|
||||||
private TestFragment mTestFragment;
|
private TestFragment mTestFragment;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mContext = ApplicationProvider.getApplicationContext();
|
mContext = ApplicationProvider.getApplicationContext();
|
||||||
|
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
mTestFragment = spy(new TestFragment());
|
mTestFragment = spy(new TestFragment());
|
||||||
doReturn(mContext).when(mTestFragment).getContext();
|
doReturn(mContext).when(mTestFragment).getContext();
|
||||||
mController = spy(new AudioStreamsProgressCategoryController(mContext, "key"));
|
mController = spy(new AudioStreamsProgressCategoryController(mContext, "key"));
|
||||||
@@ -114,6 +123,28 @@ public class AudioStreamsDashboardFragmentTest {
|
|||||||
mTestFragment.onActivityResult(
|
mTestFragment.onActivityResult(
|
||||||
REQUEST_SCAN_BT_BROADCAST_QR_CODE, Activity.RESULT_OK, intent);
|
REQUEST_SCAN_BT_BROADCAST_QR_CODE, Activity.RESULT_OK, intent);
|
||||||
verify(mController).setSourceFromQrCode(any(), any());
|
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 {
|
public static class TestFragment extends AudioStreamsDashboardFragment {
|
||||||
|
@@ -73,7 +73,7 @@ public class AudioStreamsDialogFragmentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShowDialog() {
|
public void testShowDialog_dismissAll() {
|
||||||
FragmentController.setupFragment(mFragment);
|
FragmentController.setupFragment(mFragment);
|
||||||
AudioStreamsDialogFragment.show(mFragment, mDialogBuilder, SettingsEnums.PAGE_UNKNOWN);
|
AudioStreamsDialogFragment.show(mFragment, mDialogBuilder, SettingsEnums.PAGE_UNKNOWN);
|
||||||
ShadowLooper.idleMainLooper();
|
ShadowLooper.idleMainLooper();
|
||||||
@@ -81,5 +81,8 @@ public class AudioStreamsDialogFragmentTest {
|
|||||||
var dialog = ShadowAlertDialog.getLatestAlertDialog();
|
var dialog = ShadowAlertDialog.getLatestAlertDialog();
|
||||||
assertThat(dialog).isNotNull();
|
assertThat(dialog).isNotNull();
|
||||||
assertThat(dialog.isShowing()).isTrue();
|
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);
|
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
|
@Test
|
||||||
public void testOnStart_initNoDevice_showDialog() {
|
public void testOnStart_initNoDevice_showDialog() {
|
||||||
when(mLeBroadcastAssistant.isSearchInProgress()).thenReturn(true);
|
when(mLeBroadcastAssistant.isSearchInProgress()).thenReturn(true);
|
||||||
@@ -244,6 +263,25 @@ public class AudioStreamsProgressCategoryControllerTest {
|
|||||||
verify(mController, never()).moveToState(any(), any());
|
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
|
@Test
|
||||||
public void testOnStart_handleSourceFromQrCode() {
|
public void testOnStart_handleSourceFromQrCode() {
|
||||||
// Setup a device
|
// Setup a device
|
||||||
@@ -382,6 +420,49 @@ public class AudioStreamsProgressCategoryControllerTest {
|
|||||||
assertThat(state.getValue()).isEqualTo(SYNCED);
|
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
|
@Test
|
||||||
public void testHandleSourceFound_sameIdWithSourceFromQrCode_updateMetadataAndState() {
|
public void testHandleSourceFound_sameIdWithSourceFromQrCode_updateMetadataAndState() {
|
||||||
// Setup a device
|
// Setup a device
|
||||||
@@ -518,6 +599,42 @@ public class AudioStreamsProgressCategoryControllerTest {
|
|||||||
.isEqualTo(NEWLY_FOUND_BROADCAST_ID);
|
.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
|
@Test
|
||||||
public void testHandleSourceRemoved_removed() {
|
public void testHandleSourceRemoved_removed() {
|
||||||
// Setup a device
|
// Setup a device
|
||||||
|
@@ -53,6 +53,8 @@ public class AudioStreamsProgressCategoryPreferenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAudioStreamPreference_singlePreference() {
|
public void addAudioStreamPreference_singlePreference() {
|
||||||
|
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext, null));
|
||||||
|
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||||
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||||
mPreference.addAudioStreamPreference(first, (p1, p2) -> 0);
|
mPreference.addAudioStreamPreference(first, (p1, p2) -> 0);
|
||||||
|
|
||||||
@@ -62,6 +64,8 @@ public class AudioStreamsProgressCategoryPreferenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addAudioStreamPreference_multiPreference_sorted() {
|
public void addAudioStreamPreference_multiPreference_sorted() {
|
||||||
|
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext, null, 0));
|
||||||
|
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||||
Comparator<AudioStreamPreference> c =
|
Comparator<AudioStreamPreference> c =
|
||||||
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
||||||
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||||
@@ -78,6 +82,8 @@ public class AudioStreamsProgressCategoryPreferenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void removeAudioStreamPreferences_shouldBeEmpty() {
|
public void removeAudioStreamPreferences_shouldBeEmpty() {
|
||||||
|
mPreference = spy(new AudioStreamsProgressCategoryPreference(mContext, null, 0, 0));
|
||||||
|
when(mPreference.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||||
Comparator<AudioStreamPreference> c =
|
Comparator<AudioStreamPreference> c =
|
||||||
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
Comparator.comparingInt(AudioStreamPreference::getOrder);
|
||||||
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
AudioStreamPreference first = new AudioStreamPreference(mContext, null);
|
||||||
|
@@ -97,6 +97,22 @@ public class AudioStreamsQrCodeFragmentTest {
|
|||||||
assertThat(mFragment.getMetricsCategory()).isEqualTo(SettingsEnums.AUDIO_STREAM_QR_CODE);
|
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
|
@Test
|
||||||
public void onCreateView_noMetadata_noQrCode() {
|
public void onCreateView_noMetadata_noQrCode() {
|
||||||
List<BluetoothLeBroadcastMetadata> list = new ArrayList<>();
|
List<BluetoothLeBroadcastMetadata> list = new ArrayList<>();
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows;
|
package com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -69,4 +70,16 @@ public class ShadowAudioStreamsHelper {
|
|||||||
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
||||||
return sMockHelper.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