Use LocalBluetoothLeBroadcastSourceState
.
Test: atest Bug: 308368124 Flag: com.android.settingslib.flags.enable_le_audio_sharing Change-Id: Ic49a6782b63c91e95dd16898b5443585068e45f0
This commit is contained in:
@@ -82,7 +82,7 @@ public class BluetoothDetailsAudioSharingController extends BluetoothDetailsCont
|
||||
mProfilesContainer.removeAll();
|
||||
mProfilesContainer.addPreference(createAudioSharingPreference());
|
||||
if ((BluetoothUtils.isActiveLeAudioDevice(mCachedDevice)
|
||||
|| AudioStreamsHelper.hasConnectedBroadcastSource(
|
||||
|| AudioStreamsHelper.hasBroadcastSource(
|
||||
mCachedDevice, mLocalBluetoothManager))
|
||||
&& !BluetoothUtils.isBroadcasting(mLocalBluetoothManager)) {
|
||||
mProfilesContainer.addPreference(createFindAudioStreamPreference());
|
||||
|
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.getLocalSourceState;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||
@@ -42,7 +46,6 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.settingslib.widget.ActionButtonsPreference;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -75,20 +78,19 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
int sourceId,
|
||||
BluetoothLeBroadcastReceiveState state) {
|
||||
super.onReceiveStateChanged(sink, sourceId, state);
|
||||
boolean shouldUpdateButton =
|
||||
BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)
|
||||
? AudioStreamsHelper.hasSourcePresent(state)
|
||||
: AudioStreamsHelper.isConnected(state);
|
||||
var localSourceState = getLocalSourceState(state);
|
||||
boolean shouldUpdateButton = mHysteresisModeFixAvailable
|
||||
? (localSourceState == PAUSED || localSourceState == STREAMING)
|
||||
: localSourceState == STREAMING;
|
||||
if (shouldUpdateButton) {
|
||||
updateButton();
|
||||
if (AudioStreamsHelper.isConnected(state)) {
|
||||
// TODO(b/308368124): Verify if this log is too noisy.
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext,
|
||||
SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED,
|
||||
SOURCE_ORIGIN_REPOSITORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSourceAddFailed(
|
||||
@@ -113,6 +115,7 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
private final AudioStreamsHelper mAudioStreamsHelper;
|
||||
private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private final boolean mHysteresisModeFixAvailable;
|
||||
private @Nullable ActionButtonsPreference mPreference;
|
||||
private int mBroadcastId = -1;
|
||||
|
||||
@@ -121,6 +124,8 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
mExecutor = Executors.newSingleThreadExecutor();
|
||||
mAudioStreamsHelper = new AudioStreamsHelper(Utils.getLocalBtManager(context));
|
||||
mLeBroadcastAssistant = mAudioStreamsHelper.getLeBroadcastAssistant();
|
||||
mHysteresisModeFixAvailable = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(
|
||||
context);
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
@@ -155,14 +160,8 @@ public class AudioStreamButtonController extends BasePreferenceController
|
||||
return;
|
||||
}
|
||||
|
||||
List<BluetoothLeBroadcastReceiveState> sources =
|
||||
BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)
|
||||
? mAudioStreamsHelper.getAllPresentSources()
|
||||
: mAudioStreamsHelper.getAllConnectedSources();
|
||||
boolean isConnected =
|
||||
sources.stream()
|
||||
.map(BluetoothLeBroadcastReceiveState::getBroadcastId)
|
||||
.anyMatch(connectedBroadcastId -> connectedBroadcastId == mBroadcastId);
|
||||
boolean isConnected = mAudioStreamsHelper.getConnectedBroadcastIdAndState(
|
||||
mHysteresisModeFixAvailable).containsKey(mBroadcastId);
|
||||
|
||||
View.OnClickListener onClickListener;
|
||||
|
||||
|
@@ -16,9 +16,10 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.getLocalSourceState;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastAssistant;
|
||||
@@ -61,6 +62,7 @@ public class AudioStreamHeaderController extends BasePreferenceController
|
||||
private final Executor mExecutor;
|
||||
private final AudioStreamsHelper mAudioStreamsHelper;
|
||||
@Nullable private final LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||
private final boolean mHysteresisModeFixAvailable;
|
||||
|
||||
@VisibleForTesting
|
||||
final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
|
||||
@@ -83,13 +85,13 @@ public class AudioStreamHeaderController extends BasePreferenceController
|
||||
int sourceId,
|
||||
BluetoothLeBroadcastReceiveState state) {
|
||||
super.onReceiveStateChanged(sink, sourceId, state);
|
||||
if (AudioStreamsHelper.isConnected(state)) {
|
||||
var localSourceState = getLocalSourceState(state);
|
||||
if (localSourceState == STREAMING) {
|
||||
updateSummary();
|
||||
mAudioStreamsHelper.startMediaService(
|
||||
mContext, mBroadcastId, mBroadcastName);
|
||||
} else if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)
|
||||
&& AudioStreamsHelper.hasSourcePresent(state)) {
|
||||
// if source present but not connected, only update the summary
|
||||
} else if (mHysteresisModeFixAvailable && localSourceState == PAUSED) {
|
||||
// if source paused, only update the summary
|
||||
updateSummary();
|
||||
}
|
||||
}
|
||||
@@ -105,6 +107,8 @@ public class AudioStreamHeaderController extends BasePreferenceController
|
||||
mExecutor = Executors.newSingleThreadExecutor();
|
||||
mAudioStreamsHelper = new AudioStreamsHelper(Utils.getLocalBtManager(context));
|
||||
mLeBroadcastAssistant = mAudioStreamsHelper.getLeBroadcastAssistant();
|
||||
mHysteresisModeFixAvailable = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(
|
||||
context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,38 +155,9 @@ public class AudioStreamHeaderController extends BasePreferenceController
|
||||
var unused =
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
() -> {
|
||||
var connectedSourceList =
|
||||
mAudioStreamsHelper.getAllPresentSources().stream()
|
||||
.filter(
|
||||
state ->
|
||||
(state.getBroadcastId()
|
||||
== mBroadcastId))
|
||||
.collect(toList());
|
||||
|
||||
var latestSummary =
|
||||
audioSharingHysteresisModeFix()
|
||||
? connectedSourceList.isEmpty()
|
||||
? AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY
|
||||
: (connectedSourceList.stream()
|
||||
.anyMatch(
|
||||
AudioStreamsHelper
|
||||
::isConnected)
|
||||
? mContext.getString(
|
||||
AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY)
|
||||
: mContext.getString(
|
||||
AUDIO_STREAM_HEADER_PRESENT_NOW_SUMMARY))
|
||||
: mAudioStreamsHelper.getAllConnectedSources().stream()
|
||||
.map(
|
||||
BluetoothLeBroadcastReceiveState
|
||||
::getBroadcastId)
|
||||
.anyMatch(
|
||||
connectedBroadcastId ->
|
||||
connectedBroadcastId
|
||||
== mBroadcastId)
|
||||
? mContext.getString(
|
||||
AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY)
|
||||
: AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY;
|
||||
|
||||
var sourceState = mAudioStreamsHelper.getConnectedBroadcastIdAndState(
|
||||
mHysteresisModeFixAvailable).get(mBroadcastId);
|
||||
var latestSummary = getLatestSummary(sourceState);
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
if (mHeaderController != null) {
|
||||
@@ -212,4 +187,16 @@ public class AudioStreamHeaderController extends BasePreferenceController
|
||||
mBroadcastName = broadcastName;
|
||||
mBroadcastId = broadcastId;
|
||||
}
|
||||
|
||||
private String getLatestSummary(@Nullable LocalBluetoothLeBroadcastSourceState state) {
|
||||
if (state == null) {
|
||||
return AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY;
|
||||
}
|
||||
if (mHysteresisModeFixAvailable) {
|
||||
return state == STREAMING
|
||||
? mContext.getString(AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY)
|
||||
: mContext.getString(AUDIO_STREAM_HEADER_PRESENT_NOW_SUMMARY);
|
||||
}
|
||||
return mContext.getString(AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY);
|
||||
}
|
||||
}
|
||||
|
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
@@ -25,7 +23,6 @@ import android.app.Service;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothVolumeControl;
|
||||
import android.content.Intent;
|
||||
@@ -107,6 +104,7 @@ public class AudioStreamMediaService extends Service {
|
||||
// override this value. Otherwise, we raise the volume to 25 when the play button is clicked.
|
||||
private final AtomicInteger mLatestPositiveVolume = new AtomicInteger(25);
|
||||
private final Object mLocalSessionLock = new Object();
|
||||
private boolean mHysteresisModeFixAvailable;
|
||||
private int mBroadcastId;
|
||||
@Nullable private List<BluetoothDevice> mDevices;
|
||||
@Nullable private LocalBluetoothManager mLocalBtManager;
|
||||
@@ -139,6 +137,7 @@ public class AudioStreamMediaService extends Service {
|
||||
Log.w(TAG, "onCreate() : mLeBroadcastAssistant is null!");
|
||||
return;
|
||||
}
|
||||
mHysteresisModeFixAvailable = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(this);
|
||||
|
||||
mNotificationManager = getSystemService(NotificationManager.class);
|
||||
if (mNotificationManager == null) {
|
||||
@@ -309,13 +308,9 @@ public class AudioStreamMediaService extends Service {
|
||||
}
|
||||
|
||||
private void handleRemoveSource() {
|
||||
List<BluetoothLeBroadcastReceiveState> connected =
|
||||
mAudioStreamsHelper == null
|
||||
? emptyList()
|
||||
: mAudioStreamsHelper.getAllConnectedSources();
|
||||
if (connected.stream()
|
||||
.map(BluetoothLeBroadcastReceiveState::getBroadcastId)
|
||||
.noneMatch(id -> id == mBroadcastId)) {
|
||||
if (mAudioStreamsHelper != null
|
||||
&& !mAudioStreamsHelper.getConnectedBroadcastIdAndState(
|
||||
mHysteresisModeFixAvailable).containsKey(mBroadcastId)) {
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,12 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.BROADCAST_ID;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.BROADCAST_TITLE;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.DEVICES;
|
||||
import static com.android.settingslib.bluetooth.BluetoothUtils.isAudioSharingHysteresisModeFixAvailable;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.getLocalSourceState;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
@@ -32,6 +38,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
@@ -67,12 +74,6 @@ public class AudioStreamsHelper {
|
||||
|
||||
private final @Nullable LocalBluetoothManager mBluetoothManager;
|
||||
private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
|
||||
// Referring to Broadcast Audio Scan Service 1.0
|
||||
// Table 3.9: Broadcast Receive State characteristic format
|
||||
// 0x00000000: 0b0 = Not synchronized to BIS_index[x]
|
||||
// 0xFFFFFFFF: Failed to sync to BIG
|
||||
private static final long BIS_SYNC_NOT_SYNC_TO_BIS = 0x00000000L;
|
||||
private static final long BIS_SYNC_FAILED_SYNC_TO_BIG = 0xFFFFFFFFL;
|
||||
|
||||
AudioStreamsHelper(@Nullable LocalBluetoothManager bluetoothManager) {
|
||||
mBluetoothManager = bluetoothManager;
|
||||
@@ -141,16 +142,31 @@ public class AudioStreamsHelper {
|
||||
});
|
||||
}
|
||||
|
||||
/** Retrieves a list of all LE broadcast receive states from active sinks. */
|
||||
public List<BluetoothLeBroadcastReceiveState> getAllConnectedSources() {
|
||||
if (mLeBroadcastAssistant == null) {
|
||||
Log.w(TAG, "getAllSources(): LeBroadcastAssistant is null!");
|
||||
return emptyList();
|
||||
/**
|
||||
* Gets a map of connected broadcast IDs to their corresponding local broadcast source states.
|
||||
*
|
||||
* <p>If multiple sources have the same broadcast ID, the state of the source that is
|
||||
* {@code STREAMING} is preferred.
|
||||
*/
|
||||
public Map<Integer, LocalBluetoothLeBroadcastSourceState> getConnectedBroadcastIdAndState(
|
||||
boolean hysteresisModeFixAvailable) {
|
||||
if (mBluetoothManager == null || mLeBroadcastAssistant == null) {
|
||||
Log.w(TAG,
|
||||
"getConnectedBroadcastIdAndState(): BluetoothManager or LeBroadcastAssistant "
|
||||
+ "is null!");
|
||||
return emptyMap();
|
||||
}
|
||||
return getConnectedBluetoothDevices(mBluetoothManager, /* inSharingOnly= */ true).stream()
|
||||
.flatMap(sink -> mLeBroadcastAssistant.getAllSources(sink).stream())
|
||||
.filter(AudioStreamsHelper::isConnected)
|
||||
.toList();
|
||||
.map(state -> new Pair<>(state.getBroadcastId(), getLocalSourceState(state)))
|
||||
.filter(pair -> pair.second == STREAMING
|
||||
|| (hysteresisModeFixAvailable && pair.second == PAUSED))
|
||||
.collect(toMap(
|
||||
p -> p.first,
|
||||
p -> p.second,
|
||||
(existingState, newState) -> existingState == STREAMING ? existingState
|
||||
: newState
|
||||
));
|
||||
}
|
||||
|
||||
/** Retrieves a list of all LE broadcast receive states keyed by each active device. */
|
||||
@@ -163,47 +179,12 @@ public class AudioStreamsHelper {
|
||||
.collect(toMap(Function.identity(), mLeBroadcastAssistant::getAllSources));
|
||||
}
|
||||
|
||||
/** Retrieves a list of all LE broadcast receive states from sinks with source present. */
|
||||
@VisibleForTesting
|
||||
public List<BluetoothLeBroadcastReceiveState> getAllPresentSources() {
|
||||
if (mLeBroadcastAssistant == null) {
|
||||
Log.w(TAG, "getAllPresentSources(): LeBroadcastAssistant is null!");
|
||||
return emptyList();
|
||||
}
|
||||
return getConnectedBluetoothDevices(mBluetoothManager, /* inSharingOnly= */ true).stream()
|
||||
.flatMap(sink -> mLeBroadcastAssistant.getAllSources(sink).stream())
|
||||
.filter(AudioStreamsHelper::hasSourcePresent)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/** Retrieves LocalBluetoothLeBroadcastAssistant. */
|
||||
@Nullable
|
||||
public LocalBluetoothLeBroadcastAssistant getLeBroadcastAssistant() {
|
||||
return mLeBroadcastAssistant;
|
||||
}
|
||||
|
||||
/** Checks the connectivity status based on the provided broadcast receive state. */
|
||||
public static boolean isConnected(BluetoothLeBroadcastReceiveState state) {
|
||||
return state.getBisSyncState().stream()
|
||||
.anyMatch(
|
||||
bitmap ->
|
||||
(bitmap != BIS_SYNC_NOT_SYNC_TO_BIS
|
||||
&& bitmap != BIS_SYNC_FAILED_SYNC_TO_BIG));
|
||||
}
|
||||
|
||||
/** Checks the connectivity status based on the provided broadcast receive state. */
|
||||
public static boolean hasSourcePresent(BluetoothLeBroadcastReceiveState state) {
|
||||
// Referring to Broadcast Audio Scan Service 1.0
|
||||
// All zero address means no source on the sink device
|
||||
return !state.getSourceDevice().getAddress().equals("00:00:00:00:00:00");
|
||||
}
|
||||
|
||||
static boolean isBadCode(BluetoothLeBroadcastReceiveState state) {
|
||||
return state.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED
|
||||
&& state.getBigEncryptionState()
|
||||
== BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code CachedBluetoothDevice} that is either connected to a broadcast source or is
|
||||
* a connected LE device.
|
||||
@@ -226,7 +207,7 @@ public class AudioStreamsHelper {
|
||||
}
|
||||
var deviceHasSource =
|
||||
leadDevices.stream()
|
||||
.filter(device -> hasConnectedBroadcastSource(device, manager))
|
||||
.filter(device -> hasBroadcastSource(device, manager))
|
||||
.findFirst();
|
||||
if (deviceHasSource.isPresent()) {
|
||||
Log.d(
|
||||
@@ -258,38 +239,38 @@ public class AudioStreamsHelper {
|
||||
return Optional.empty();
|
||||
}
|
||||
return leadDevices.stream()
|
||||
.filter(device -> hasConnectedBroadcastSource(device, manager))
|
||||
.filter(device -> hasBroadcastSource(device, manager))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if {@link CachedBluetoothDevice} has connected to a broadcast source.
|
||||
* Check if {@link CachedBluetoothDevice} has a broadcast source that is in STREAMING, PAUSED
|
||||
* or DECRYPTION_FAILED state.
|
||||
*
|
||||
* @param cachedDevice The cached bluetooth device to check.
|
||||
* @param localBtManager The BT manager to provide BT functions.
|
||||
* @return Whether the device has connected to a broadcast source.
|
||||
* @return Whether the device has a broadcast source.
|
||||
*/
|
||||
public static boolean hasConnectedBroadcastSource(
|
||||
public static boolean hasBroadcastSource(
|
||||
CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager) {
|
||||
if (localBtManager == null) {
|
||||
Log.d(TAG, "Skip check hasConnectedBroadcastSource due to bt manager is null");
|
||||
Log.d(TAG, "Skip check hasBroadcastSource due to bt manager is null");
|
||||
return false;
|
||||
}
|
||||
LocalBluetoothLeBroadcastAssistant assistant =
|
||||
localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
|
||||
if (assistant == null) {
|
||||
Log.d(TAG, "Skip check hasConnectedBroadcastSource due to assistant profile is null");
|
||||
Log.d(TAG, "Skip check hasBroadcastSource due to assistant profile is null");
|
||||
return false;
|
||||
}
|
||||
List<BluetoothLeBroadcastReceiveState> sourceList =
|
||||
assistant.getAllSources(cachedDevice.getDevice());
|
||||
if (!sourceList.isEmpty()
|
||||
&& (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(
|
||||
localBtManager.getContext())
|
||||
|| sourceList.stream().anyMatch(AudioStreamsHelper::isConnected))) {
|
||||
boolean hysteresisModeFixAvailable = isAudioSharingHysteresisModeFixAvailable(
|
||||
localBtManager.getContext());
|
||||
if (hasReceiveState(sourceList, hysteresisModeFixAvailable)) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"Lead device has connected broadcast source, device = "
|
||||
"Lead device has broadcast source, device = "
|
||||
+ cachedDevice.getDevice().getAnonymizedAddress());
|
||||
return true;
|
||||
}
|
||||
@@ -297,13 +278,10 @@ public class AudioStreamsHelper {
|
||||
for (CachedBluetoothDevice device : cachedDevice.getMemberDevice()) {
|
||||
List<BluetoothLeBroadcastReceiveState> list =
|
||||
assistant.getAllSources(device.getDevice());
|
||||
if (!list.isEmpty()
|
||||
&& (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(
|
||||
localBtManager.getContext())
|
||||
|| list.stream().anyMatch(AudioStreamsHelper::isConnected))) {
|
||||
if (hasReceiveState(list, hysteresisModeFixAvailable)) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"Member device has connected broadcast source, device = "
|
||||
"Member device has broadcast source, device = "
|
||||
+ device.getDevice().getAnonymizedAddress());
|
||||
return true;
|
||||
}
|
||||
@@ -311,6 +289,18 @@ public class AudioStreamsHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasReceiveState(List<BluetoothLeBroadcastReceiveState> states,
|
||||
boolean hysteresisModeFixAvailable) {
|
||||
return states.stream().anyMatch(state -> {
|
||||
var localSourceState = getLocalSourceState(state);
|
||||
if (hysteresisModeFixAvailable) {
|
||||
return localSourceState == STREAMING || localSourceState == DECRYPTION_FAILED
|
||||
|| localSourceState == PAUSED;
|
||||
}
|
||||
return localSourceState == STREAMING || localSourceState == DECRYPTION_FAILED;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of connected Bluetooth devices that belongs to one {@link
|
||||
* CachedBluetoothDevice} that's either connected to a broadcast source or is a connected LE
|
||||
|
@@ -16,23 +16,17 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.getLocalSourceState;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
|
||||
public class AudioStreamsProgressCategoryCallback extends AudioStreamsBroadcastAssistantCallback {
|
||||
private static final String TAG = "AudioStreamsProgressCategoryCallback";
|
||||
|
||||
private final Context mContext;
|
||||
private final AudioStreamsProgressCategoryController mCategoryController;
|
||||
|
||||
public AudioStreamsProgressCategoryCallback(
|
||||
Context context,
|
||||
AudioStreamsProgressCategoryController audioStreamsProgressCategoryController) {
|
||||
mContext = context;
|
||||
mCategoryController = audioStreamsProgressCategoryController;
|
||||
}
|
||||
|
||||
@@ -40,15 +34,11 @@ public class AudioStreamsProgressCategoryCallback extends AudioStreamsBroadcastA
|
||||
public void onReceiveStateChanged(
|
||||
BluetoothDevice sink, int sourceId, BluetoothLeBroadcastReceiveState state) {
|
||||
super.onReceiveStateChanged(sink, sourceId, state);
|
||||
|
||||
if (AudioStreamsHelper.isConnected(state)) {
|
||||
mCategoryController.handleSourceConnected(sink, state);
|
||||
} else if (AudioStreamsHelper.isBadCode(state)) {
|
||||
mCategoryController.handleSourceConnectBadCode(state);
|
||||
} else if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext)
|
||||
&& AudioStreamsHelper.hasSourcePresent(state)) {
|
||||
// Keep this check as the last, source might also present in above states
|
||||
mCategoryController.handleSourcePresent(sink, state);
|
||||
var sourceState = getLocalSourceState(state);
|
||||
switch (sourceState) {
|
||||
case STREAMING -> mCategoryController.handleSourceStreaming(sink, state);
|
||||
case DECRYPTION_FAILED -> mCategoryController.handleSourceConnectBadCode(state);
|
||||
case PAUSED -> mCategoryController.handleSourcePaused(sink, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,12 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static com.android.settingslib.bluetooth.BluetoothUtils.isAudioSharingHysteresisModeFixAvailable;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.getLocalSourceState;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
@@ -137,6 +143,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
private final @Nullable LocalBluetoothManager mBluetoothManager;
|
||||
private final ConcurrentHashMap<Integer, AudioStreamPreference> mBroadcastIdToPreferenceMap =
|
||||
new ConcurrentHashMap<>();
|
||||
private final boolean mHysteresisModeFixAvailable;
|
||||
private @Nullable BluetoothLeBroadcastMetadata mSourceFromQrCode;
|
||||
private SourceOriginForLogging mSourceFromQrCodeOriginForLogging;
|
||||
@Nullable private AudioStreamsProgressCategoryPreference mCategoryPreference;
|
||||
@@ -149,7 +156,9 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
mAudioStreamsHelper = new AudioStreamsHelper(mBluetoothManager);
|
||||
mMediaControlHelper = new MediaControlHelper(mContext, mBluetoothManager);
|
||||
mLeBroadcastAssistant = mAudioStreamsHelper.getLeBroadcastAssistant();
|
||||
mBroadcastAssistantCallback = new AudioStreamsProgressCategoryCallback(context, this);
|
||||
mBroadcastAssistantCallback = new AudioStreamsProgressCategoryCallback(this);
|
||||
mHysteresisModeFixAvailable = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(
|
||||
mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -260,7 +269,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
// change it's state.
|
||||
existingPreference.setAudioStreamMetadata(source);
|
||||
if (fromState != AudioStreamState.SOURCE_ADDED
|
||||
&& (!isAudioSharingHysteresisModeFixAvailable(mContext)
|
||||
&& (!mHysteresisModeFixAvailable
|
||||
|| fromState != AudioStreamState.SOURCE_PRESENT)) {
|
||||
Log.w(
|
||||
TAG,
|
||||
@@ -336,8 +345,8 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "handleSourceLost()");
|
||||
}
|
||||
if (mAudioStreamsHelper.getAllConnectedSources().stream()
|
||||
.anyMatch(connected -> connected.getBroadcastId() == broadcastId)) {
|
||||
if (mAudioStreamsHelper.getConnectedBroadcastIdAndState(
|
||||
mHysteresisModeFixAvailable).containsKey(broadcastId)) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"handleSourceLost() : keep this preference as the source is still connected.");
|
||||
@@ -366,14 +375,12 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
// not, means the source is removed from the sink, we move back the preference to SYNCED
|
||||
// state.
|
||||
if ((preference.getAudioStreamState() == AudioStreamState.SOURCE_ADDED
|
||||
|| (isAudioSharingHysteresisModeFixAvailable(mContext)
|
||||
|| (mHysteresisModeFixAvailable
|
||||
&& preference.getAudioStreamState()
|
||||
== AudioStreamState.SOURCE_PRESENT))
|
||||
&& mAudioStreamsHelper.getAllConnectedSources().stream()
|
||||
.noneMatch(
|
||||
connected ->
|
||||
connected.getBroadcastId()
|
||||
== preference.getAudioStreamBroadcastId())) {
|
||||
&& !mAudioStreamsHelper.getConnectedBroadcastIdAndState(
|
||||
mHysteresisModeFixAvailable).containsKey(
|
||||
preference.getAudioStreamBroadcastId())) {
|
||||
|
||||
ThreadUtils.postOnMainThread(
|
||||
() -> {
|
||||
@@ -395,27 +402,27 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
// Expect one of the following:
|
||||
// 1) No preference existed, create new preference with state SOURCE_ADDED
|
||||
// 2) Any other state, move to SOURCE_ADDED
|
||||
void handleSourceConnected(
|
||||
void handleSourceStreaming(
|
||||
BluetoothDevice device, BluetoothLeBroadcastReceiveState receiveState) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "handleSourceConnected()");
|
||||
Log.d(TAG, "handleSourceStreaming()");
|
||||
}
|
||||
if (!AudioStreamsHelper.isConnected(receiveState)) {
|
||||
if (getLocalSourceState(receiveState) != STREAMING) {
|
||||
return;
|
||||
}
|
||||
var broadcastIdConnected = receiveState.getBroadcastId();
|
||||
var broadcastIdStreaming = receiveState.getBroadcastId();
|
||||
Optional<BluetoothLeBroadcastMetadata> metadata =
|
||||
getMetadataMatchingByBroadcastId(
|
||||
device, receiveState.getSourceId(), broadcastIdConnected);
|
||||
device, receiveState.getSourceId(), broadcastIdStreaming);
|
||||
handleQrCodeWithUnsetBroadcastIdIfNeeded(metadata, receiveState);
|
||||
mBroadcastIdToPreferenceMap.compute(
|
||||
broadcastIdConnected,
|
||||
broadcastIdStreaming,
|
||||
(k, existingPreference) -> {
|
||||
if (existingPreference == null) {
|
||||
// No existing preference for this source even if it's already connected,
|
||||
// No existing preference for this source even if it's already streaming,
|
||||
// add one and set initial state to SOURCE_ADDED. This could happen because
|
||||
// we retrieves the connected source during onStart() from
|
||||
// AudioStreamsHelper#getAllConnectedSources() even before the source is
|
||||
// we retrieves the streaming source during onStart() from
|
||||
// AudioStreamsHelper#getAllStreamingSources() even before the source is
|
||||
// founded by scanning.
|
||||
return metadata.isPresent()
|
||||
? addNewPreference(
|
||||
@@ -440,7 +447,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "handleSourceConnectBadCode()");
|
||||
}
|
||||
if (!AudioStreamsHelper.isBadCode(receiveState)) {
|
||||
if (getLocalSourceState(receiveState) != DECRYPTION_FAILED) {
|
||||
return;
|
||||
}
|
||||
mBroadcastIdToPreferenceMap.computeIfPresent(
|
||||
@@ -467,29 +474,28 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
|
||||
// Find preference by receiveState and decide next state.
|
||||
// Expect one preference existed, move to SOURCE_PRESENT
|
||||
void handleSourcePresent(
|
||||
void handleSourcePaused(
|
||||
BluetoothDevice device, BluetoothLeBroadcastReceiveState receiveState) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "handleSourcePresent()");
|
||||
Log.d(TAG, "handleSourcePaused()");
|
||||
}
|
||||
if (!AudioStreamsHelper.hasSourcePresent(receiveState)) {
|
||||
if (!mHysteresisModeFixAvailable || getLocalSourceState(receiveState) != PAUSED) {
|
||||
return;
|
||||
}
|
||||
|
||||
var broadcastIdConnected = receiveState.getBroadcastId();
|
||||
var broadcastIdPaused = receiveState.getBroadcastId();
|
||||
Optional<BluetoothLeBroadcastMetadata> metadata =
|
||||
getMetadataMatchingByBroadcastId(
|
||||
device, receiveState.getSourceId(), broadcastIdConnected);
|
||||
device, receiveState.getSourceId(), broadcastIdPaused);
|
||||
handleQrCodeWithUnsetBroadcastIdIfNeeded(metadata, receiveState);
|
||||
mBroadcastIdToPreferenceMap.compute(
|
||||
broadcastIdConnected,
|
||||
broadcastIdPaused,
|
||||
(k, existingPreference) -> {
|
||||
if (existingPreference == null) {
|
||||
// No existing preference for this source even if it's already connected,
|
||||
// add one and set initial state to SOURCE_PRESENT. This could happen
|
||||
// because
|
||||
// we retrieves the connected source during onStart() from
|
||||
// AudioStreamsHelper#getAllPresentSources() even before the source is
|
||||
// No existing preference for this source even if it's already existed but
|
||||
// currently paused, add one and set initial state to SOURCE_PRESENT. This
|
||||
// could happen because we retrieves the paused source during onStart() from
|
||||
// AudioStreamsHelper#getAllPausedSources() even before the source is
|
||||
// founded by scanning.
|
||||
return metadata.isPresent()
|
||||
? addNewPreference(
|
||||
@@ -580,56 +586,43 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
mLeBroadcastAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
|
||||
mExecutor.execute(
|
||||
() -> {
|
||||
// Handle QR code scan, display currently connected streams then start scanning
|
||||
// sequentially
|
||||
// Handle QR code scan, display currently streaming or paused streams then start
|
||||
// scanning sequentially
|
||||
handleSourceFromQrCodeIfExists();
|
||||
Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> sources =
|
||||
mAudioStreamsHelper.getAllSourcesByDevice();
|
||||
Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> connectedSources =
|
||||
getConnectedSources(sources);
|
||||
if (isAudioSharingHysteresisModeFixAvailable(mContext)) {
|
||||
// With hysteresis mode, we prioritize showing connected sources first.
|
||||
// If no connected sources are found, we then show present sources.
|
||||
if (!connectedSources.isEmpty()) {
|
||||
connectedSources.forEach(
|
||||
getStreamSourcesByDevice(sources).forEach(
|
||||
(device, stateList) ->
|
||||
stateList.forEach(
|
||||
state -> handleSourceConnected(device, state)));
|
||||
} else {
|
||||
Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>>
|
||||
presentSources = getPresentSources(sources);
|
||||
presentSources.forEach(
|
||||
state -> handleSourceStreaming(device, state)));
|
||||
if (mHysteresisModeFixAvailable) {
|
||||
getPausedSourcesByDevice(sources).forEach(
|
||||
(device, stateList) ->
|
||||
stateList.forEach(
|
||||
state -> handleSourcePresent(device, state)));
|
||||
}
|
||||
} else {
|
||||
connectedSources.forEach(
|
||||
(device, stateList) ->
|
||||
stateList.forEach(
|
||||
state -> handleSourceConnected(device, state)));
|
||||
state -> handleSourcePaused(device, state)));
|
||||
}
|
||||
mLeBroadcastAssistant.startSearchingForSources(emptyList());
|
||||
mMediaControlHelper.start();
|
||||
});
|
||||
}
|
||||
|
||||
private Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> getConnectedSources(
|
||||
private Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> getStreamSourcesByDevice(
|
||||
Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> sources) {
|
||||
return sources.entrySet().stream()
|
||||
.filter(
|
||||
entry ->
|
||||
entry.getValue().stream().anyMatch(AudioStreamsHelper::isConnected))
|
||||
entry.getValue().stream().anyMatch(
|
||||
state -> getLocalSourceState(state) == STREAMING))
|
||||
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
private Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> getPresentSources(
|
||||
private Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> getPausedSourcesByDevice(
|
||||
Map<BluetoothDevice, List<BluetoothLeBroadcastReceiveState>> sources) {
|
||||
return sources.entrySet().stream()
|
||||
.filter(
|
||||
entry ->
|
||||
entry.getValue().stream()
|
||||
.anyMatch(AudioStreamsHelper::hasSourcePresent))
|
||||
.anyMatch(state -> getLocalSourceState(state) == PAUSED))
|
||||
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
@@ -742,8 +735,4 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro
|
||||
dialog.dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isAudioSharingHysteresisModeFixAvailable(Context context) {
|
||||
return BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context);
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -143,9 +144,12 @@ public class BluetoothDetailsAudioSharingControllerTest extends BluetoothDetails
|
||||
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
|
||||
public void connected_hasConnectedBroadcastSource_showTwoPreference() {
|
||||
public void connected_hasBroadcastSource_showTwoPreference() {
|
||||
when(mCachedDevice.isConnectedLeAudioDevice()).thenReturn(true);
|
||||
when(mCachedDevice.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false);
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
when(mBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
|
||||
when(mLocalManager
|
||||
.getProfileManager()
|
||||
.getLeAudioBroadcastAssistantProfile()
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING;
|
||||
|
||||
@@ -71,6 +73,7 @@ import org.robolectric.shadow.api.Shadow;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -164,9 +167,9 @@ public class AudioStreamButtonControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourceConnected_setDisconnectButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
public void testDisplayPreference_sourceStreaming_setDisconnectButton() {
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, STREAMING));
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
@@ -190,7 +193,8 @@ public class AudioStreamButtonControllerTest {
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourceNotConnected_setConnectButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
mController.setAudioStreamsRepositoryForTesting(mRepository);
|
||||
var metadataToRejoin = mock(BluetoothLeBroadcastMetadata.class);
|
||||
when(mRepository.getSavedMetadata(any(), anyInt())).thenReturn(metadataToRejoin);
|
||||
@@ -216,7 +220,8 @@ public class AudioStreamButtonControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceRemoved_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceRemoved(
|
||||
@@ -230,9 +235,8 @@ public class AudioStreamButtonControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceRemovedFailed_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, STREAMING));
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceRemoveFailed(
|
||||
@@ -250,9 +254,8 @@ public class AudioStreamButtonControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onReceiveStateChanged_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, STREAMING));
|
||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
@@ -273,7 +276,7 @@ public class AudioStreamButtonControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallback_onReceiveStateChangedWithSourcePresent_updateButton() {
|
||||
public void testCallback_onReceiveStateChangedWithSourcePaused_updateButton() {
|
||||
mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
String address = "11:22:33:44:55:66";
|
||||
@@ -284,13 +287,16 @@ public class AudioStreamButtonControllerTest {
|
||||
when(mSourceDevice.getAddress()).thenReturn(address);
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
when(state.getBisSyncState()).thenReturn(bisSyncState);
|
||||
when(mAudioStreamsHelper.getAllPresentSources()).thenReturn(List.of(state));
|
||||
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, PAUSED));
|
||||
// Create new controller to enable hysteresis mode
|
||||
mController = new AudioStreamButtonController(mContext, KEY);
|
||||
mController.init(BROADCAST_ID);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
||||
mock(BluetoothDevice.class), /* sourceId= */ 0, state);
|
||||
|
||||
verify(mFeatureFactory.metricsFeatureProvider, never())
|
||||
verify(mFeatureFactory.metricsFeatureProvider)
|
||||
.action(any(), eq(SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED), anyInt());
|
||||
|
||||
// Called twice, once in displayPreference, the other one in callback
|
||||
@@ -302,7 +308,8 @@ public class AudioStreamButtonControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceAddFailed_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceAddFailed(
|
||||
@@ -321,7 +328,8 @@ public class AudioStreamButtonControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceLost_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 0);
|
||||
|
@@ -19,10 +19,13 @@ 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 com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamHeaderController.AUDIO_STREAM_HEADER_PRESENT_NOW_SUMMARY;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -66,6 +69,7 @@ import org.robolectric.shadow.api.Shadow;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -160,10 +164,9 @@ public class AudioStreamHeaderControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourceConnected_setSummary() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
public void testDisplayPreference_sourceStreaming_setSummary() {
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, STREAMING));
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
@@ -176,8 +179,9 @@ public class AudioStreamHeaderControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourceNotConnected_setSummary() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
public void testDisplayPreference_sourceNotStreaming_setSummary() {
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
@@ -189,18 +193,14 @@ public class AudioStreamHeaderControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourcePresent_setSummary() {
|
||||
public void testDisplayPreference_sourcePaused_setSummary() {
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
String address = "11:22:33:44:55:66";
|
||||
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
when(mBroadcastReceiveState.getSourceDevice()).thenReturn(mBluetoothDevice);
|
||||
when(mBluetoothDevice.getAddress()).thenReturn(address);
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
when(mBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
|
||||
when(mAudioStreamsHelper.getAllPresentSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, PAUSED));
|
||||
|
||||
// Create new controller to enable hysteresis mode
|
||||
mController = new AudioStreamHeaderController(mContext, KEY);
|
||||
mController.init(mFragment, BROADCAST_NAME, BROADCAST_ID);
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
verify(mHeaderController).setLabel(BROADCAST_NAME);
|
||||
@@ -212,10 +212,10 @@ public class AudioStreamHeaderControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayPreference_sourceNotPresent_setSummary() {
|
||||
public void testDisplayPreference_sourceNotPaused_setSummary() {
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
|
||||
when(mAudioStreamsHelper.getAllPresentSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
@@ -228,7 +228,8 @@ public class AudioStreamHeaderControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceRemoved_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceRemoved(
|
||||
@@ -241,7 +242,8 @@ public class AudioStreamHeaderControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onSourceLost_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(Collections.emptyList());
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Collections.emptyMap());
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
||||
@@ -253,8 +255,8 @@ public class AudioStreamHeaderControllerTest {
|
||||
|
||||
@Test
|
||||
public void testCallback_onReceiveStateChanged_updateButton() {
|
||||
when(mAudioStreamsHelper.getAllConnectedSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, STREAMING));
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
@@ -272,17 +274,20 @@ public class AudioStreamHeaderControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallback_onReceiveStateChangedWithSourcePresent_updateButton() {
|
||||
public void testCallback_onReceiveStateChangedWithSourcePaused_updateButton() {
|
||||
mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
String address = "11:22:33:44:55:66";
|
||||
|
||||
when(mAudioStreamsHelper.getAllPresentSources())
|
||||
.thenReturn(List.of(mBroadcastReceiveState));
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean()))
|
||||
.thenReturn(Map.of(BROADCAST_ID, PAUSED));
|
||||
when(mBroadcastReceiveState.getBroadcastId()).thenReturn(BROADCAST_ID);
|
||||
when(mBroadcastReceiveState.getSourceDevice()).thenReturn(mBluetoothDevice);
|
||||
when(mBluetoothDevice.getAddress()).thenReturn(address);
|
||||
|
||||
// Create new controller to enable hysteresis mode
|
||||
mController = new AudioStreamHeaderController(mContext, KEY);
|
||||
mController.init(mFragment, BROADCAST_NAME, BROADCAST_ID);
|
||||
mController.displayPreference(mScreen);
|
||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
||||
mock(BluetoothDevice.class), /* sourceId= */ 0, mBroadcastReceiveState);
|
||||
|
@@ -19,6 +19,8 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING;
|
||||
|
||||
@@ -149,11 +151,14 @@ public class AudioStreamsHelperTest {
|
||||
|
||||
@Test
|
||||
public void removeSource_noConnectedSource_doNothing() {
|
||||
String address = "11:22:33:44:55:66";
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
|
||||
BluetoothLeBroadcastReceiveState source = mock(BluetoothLeBroadcastReceiveState.class);
|
||||
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_2);
|
||||
when(source.getSourceDevice()).thenReturn(mSourceDevice);
|
||||
when(mSourceDevice.getAddress()).thenReturn(address);
|
||||
when(mDeviceManager.findDevice(any())).thenReturn(mCachedDevice);
|
||||
when(mCachedDevice.getDevice()).thenReturn(mDevice);
|
||||
when(mCachedDevice.getGroupId()).thenReturn(GROUP_ID);
|
||||
@@ -214,15 +219,16 @@ public class AudioStreamsHelperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllConnectedSources_noAssistant() {
|
||||
public void getConnectedBroadcastIdAndState_noAssistant() {
|
||||
when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(null);
|
||||
mHelper = new AudioStreamsHelper(mLocalBluetoothManager);
|
||||
|
||||
assertThat(mHelper.getAllConnectedSources()).isEmpty();
|
||||
assertThat(mHelper.getConnectedBroadcastIdAndState(/* hysteresisModeFixAvailable= */
|
||||
false)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllConnectedSources_returnSource() {
|
||||
public void getConnectedBroadcastIdAndState_returnStreamingSource() {
|
||||
List<BluetoothDevice> devices = new ArrayList<>();
|
||||
devices.add(mDevice);
|
||||
when(mAssistant.getAllConnectedDevices()).thenReturn(devices);
|
||||
@@ -234,14 +240,15 @@ public class AudioStreamsHelperTest {
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
bisSyncState.add(1L);
|
||||
when(source.getBisSyncState()).thenReturn(bisSyncState);
|
||||
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_1);
|
||||
|
||||
var list = mHelper.getAllConnectedSources();
|
||||
assertThat(list).isNotEmpty();
|
||||
assertThat(list.get(0)).isEqualTo(source);
|
||||
var map = mHelper.getConnectedBroadcastIdAndState(/* hysteresisModeFixAvailable= */ false);
|
||||
assertThat(map).isNotEmpty();
|
||||
assertThat(map.get(BROADCAST_ID_1)).isEqualTo(STREAMING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllPresentSources_noSource() {
|
||||
public void getConnectedBroadcastIdAndState_noSource() {
|
||||
mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
|
||||
@@ -259,12 +266,12 @@ public class AudioStreamsHelperTest {
|
||||
when(source.getSourceDevice()).thenReturn(mSourceDevice);
|
||||
when(mSourceDevice.getAddress()).thenReturn(address);
|
||||
|
||||
var list = mHelper.getAllPresentSources();
|
||||
assertThat(list).isEmpty();
|
||||
var map = mHelper.getConnectedBroadcastIdAndState(/* hysteresisModeFixAvailable= */ true);
|
||||
assertThat(map).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllPresentSources_returnSource() {
|
||||
public void getConnectedBroadcastIdAndState_returnPausedSource() {
|
||||
mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
String address = "11:22:33:44:55:66";
|
||||
@@ -282,10 +289,11 @@ public class AudioStreamsHelperTest {
|
||||
when(mSourceDevice.getAddress()).thenReturn(address);
|
||||
List<Long> bisSyncState = new ArrayList<>();
|
||||
when(source.getBisSyncState()).thenReturn(bisSyncState);
|
||||
when(source.getBroadcastId()).thenReturn(BROADCAST_ID_1);
|
||||
|
||||
var list = mHelper.getAllPresentSources();
|
||||
assertThat(list).isNotEmpty();
|
||||
assertThat(list.get(0)).isEqualTo(source);
|
||||
var map = mHelper.getConnectedBroadcastIdAndState(/* hysteresisModeFixAvailable= */ true);
|
||||
assertThat(map).isNotEmpty();
|
||||
assertThat(map.get(BROADCAST_ID_1)).isEqualTo(PAUSED);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -77,7 +77,7 @@ public class AudioStreamsProgressCategoryCallbackTest {
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
|
||||
BluetoothStatusCodes.FEATURE_SUPPORTED);
|
||||
mCallback = new AudioStreamsProgressCategoryCallback(mContext, mController);
|
||||
mCallback = new AudioStreamsProgressCategoryCallback(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -87,7 +87,7 @@ public class AudioStreamsProgressCategoryCallbackTest {
|
||||
when(mState.getBisSyncState()).thenReturn(bisSyncState);
|
||||
mCallback.onReceiveStateChanged(mDevice, /* sourceId= */ 0, mState);
|
||||
|
||||
verify(mController).handleSourceConnected(any(), any());
|
||||
verify(mController).handleSourceStreaming(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,7 +102,7 @@ public class AudioStreamsProgressCategoryCallbackTest {
|
||||
when(mSourceDevice.getAddress()).thenReturn(address);
|
||||
mCallback.onReceiveStateChanged(mDevice, /* sourceId= */ 0, mState);
|
||||
|
||||
verify(mController).handleSourcePresent(any(), any());
|
||||
verify(mController).handleSourcePaused(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -25,6 +25,7 @@ import static com.android.settings.connecteddevice.audiosharing.audiostreams.Aud
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsProgressCategoryController.AudioStreamState.WAIT_FOR_SYNC;
|
||||
import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsProgressCategoryController.UNSET_BROADCAST_ID;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX;
|
||||
import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING;
|
||||
|
||||
@@ -355,7 +356,7 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStart_handleSourceAlreadyConnected_useNameFromMetadata() {
|
||||
public void testOnStart_handleSourceAlreadyStreaming_useNameFromMetadata() {
|
||||
// Setup a device
|
||||
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(mDevice);
|
||||
|
||||
@@ -665,8 +666,8 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
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));
|
||||
when(mAudioStreamsHelper.getConnectedBroadcastIdAndState(anyBoolean())).thenReturn(
|
||||
Map.of(NEWLY_FOUND_BROADCAST_ID, STREAMING));
|
||||
mController.handleSourceLost(NEWLY_FOUND_BROADCAST_ID);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
@@ -819,13 +820,15 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleSourcePresent_updateState() {
|
||||
public void testHandleSourcePaused_updateState() {
|
||||
mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX);
|
||||
String address = "11:22:33:44:55:66";
|
||||
|
||||
// Setup a device
|
||||
ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected(mDevice);
|
||||
|
||||
// Create new controller to enable hysteresis mode
|
||||
mController = spy(new TestController(mContext, KEY));
|
||||
// Setup mPreference so it's not null
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
@@ -844,7 +847,7 @@ public class AudioStreamsProgressCategoryControllerTest {
|
||||
when(receiveState.getBisSyncState()).thenReturn(bisSyncState);
|
||||
|
||||
// The new found source is identified as failed to connect
|
||||
mController.handleSourcePresent(mSourceDevice, receiveState);
|
||||
mController.handleSourcePaused(mSourceDevice, receiveState);
|
||||
shadowOf(Looper.getMainLooper()).idle();
|
||||
|
||||
ArgumentCaptor<AudioStreamPreference> preference =
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows;
|
||||
|
||||
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata;
|
||||
import android.bluetooth.BluetoothLeBroadcastReceiveState;
|
||||
@@ -57,8 +59,9 @@ public class ShadowAudioStreamsHelper {
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public List<BluetoothLeBroadcastReceiveState> getAllConnectedSources() {
|
||||
return sMockHelper.getAllConnectedSources();
|
||||
public Map<Integer, LocalBluetoothLeBroadcastSourceState> getConnectedBroadcastIdAndState(
|
||||
boolean hysteresisModeFixAvailable) {
|
||||
return sMockHelper.getConnectedBroadcastIdAndState(hysteresisModeFixAvailable);
|
||||
}
|
||||
|
||||
@Implementation
|
||||
@@ -66,11 +69,6 @@ public class ShadowAudioStreamsHelper {
|
||||
return sMockHelper.getAllSourcesByDevice();
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public List<BluetoothLeBroadcastReceiveState> getAllPresentSources() {
|
||||
return sMockHelper.getAllPresentSources();
|
||||
}
|
||||
|
||||
/** Gets {@link CachedBluetoothDevice} in sharing or le connected */
|
||||
@Implementation
|
||||
public static Optional<CachedBluetoothDevice> getCachedBluetoothDeviceInSharingOrLeConnected(
|
||||
|
Reference in New Issue
Block a user