diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java index 84b63b1a7e9..3fd5127ed7e 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java @@ -418,7 +418,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro if (isBroadcasting()) { // Show stop audio sharing dialog when an ineligible (non LE audio) remote device // connected during a sharing session. - ThreadUtils.postOnMainThread( + postOnMainThread( () -> { closeOpeningDialogs(); AudioSharingStopDialogFragment.show( @@ -442,8 +442,9 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro Map> groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(mLocalBtManager); if (isBroadcasting()) { - if (groupedDevices.containsKey(cachedDevice.getGroupId()) - && groupedDevices.get(cachedDevice.getGroupId()).stream() + int groupId = AudioSharingUtils.getGroupId(cachedDevice); + if (groupedDevices.containsKey(groupId) + && groupedDevices.get(groupId).stream() .anyMatch( device -> AudioSharingUtils.hasBroadcastSource( @@ -463,7 +464,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro // Show audio sharing switch dialog when the third eligible (LE audio) remote device // connected during a sharing session. if (deviceItemsInSharingSession.size() >= 2) { - ThreadUtils.postOnMainThread( + postOnMainThread( () -> { closeOpeningDialogs(); AudioSharingDisconnectDialogFragment.show( @@ -494,7 +495,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro } else { // Show audio sharing join dialog when the first or second eligible (LE audio) // remote device connected during a sharing session. - ThreadUtils.postOnMainThread( + postOnMainThread( () -> { closeOpeningDialogs(); AudioSharingJoinDialogFragment.show( @@ -515,7 +516,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro for (List devices : groupedDevices.values()) { // Use random device in the group within the sharing session to represent the group. CachedBluetoothDevice device = devices.get(0); - if (device.getGroupId() == cachedDevice.getGroupId()) { + if (AudioSharingUtils.getGroupId(device) + == AudioSharingUtils.getGroupId(cachedDevice)) { continue; } deviceItems.add(AudioSharingUtils.buildAudioSharingDeviceItem(device)); @@ -523,7 +525,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro // Show audio sharing join dialog when the second eligible (LE audio) remote // device connect and no sharing session. if (deviceItems.size() == 1) { - ThreadUtils.postOnMainThread( + postOnMainThread( () -> { closeOpeningDialogs(); AudioSharingJoinDialogFragment.show( @@ -599,4 +601,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro } } } + + private void postOnMainThread(@NonNull Runnable runnable) { + mContext.getMainExecutor().execute(runnable); + } } diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java index 3396b8b0f70..edd1cafeab1 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java @@ -77,11 +77,12 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre CachedBluetoothDevice cachedDevice = mLocalBtManager.getCachedDeviceManager().findDevice(device); if (cachedDevice == null) return; - mValueMap.put(cachedDevice.getGroupId(), volume); + int groupId = AudioSharingUtils.getGroupId(cachedDevice); + mValueMap.put(groupId, volume); for (AudioSharingDeviceVolumePreference preference : mVolumePreferences) { if (preference.getCachedDevice() != null - && preference.getCachedDevice().getGroupId() - == cachedDevice.getGroupId()) { + && AudioSharingUtils.getGroupId(preference.getCachedDevice()) + == groupId) { // If the callback return invalid volume, try to // get the volume from AudioManager.STREAM_MUSIC int finalVolume = getAudioVolumeIfNeeded(volume); @@ -270,7 +271,7 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre if (volumePref.getProgress() > 0) return; CachedBluetoothDevice device = volumePref.getCachedDevice(); if (device == null) return; - int volume = mValueMap.getOrDefault(device.getGroupId(), -1); + int volume = mValueMap.getOrDefault(AudioSharingUtils.getGroupId(device), -1); // If the volume is invalid, try to get the volume from AudioManager.STREAM_MUSIC int finalVolume = getAudioVolumeIfNeeded(volume); Log.d( diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java index 3d4ef82a844..924b04d3da2 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java @@ -29,10 +29,11 @@ import com.android.settings.flags.Flags; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; +import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.utils.ThreadUtils; +import com.android.settingslib.bluetooth.LocalBluetoothProfile; import java.util.ArrayList; import java.util.HashMap; @@ -57,10 +58,16 @@ public class AudioSharingUtils { public static Map> fetchConnectedDevicesByGroupId( LocalBluetoothManager localBtManager) { Map> groupedDevices = new HashMap<>(); + if (localBtManager == null) { + Log.d(TAG, "Skip fetchConnectedDevicesByGroupId due to bt manager is null"); + return groupedDevices; + } LocalBluetoothLeBroadcastAssistant assistant = localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile(); - if (assistant == null) return groupedDevices; - // TODO: filter out devices with le audio disabled. + if (assistant == null) { + Log.d(TAG, "Skip fetchConnectedDevicesByGroupId due to assistant profile is null"); + return groupedDevices; + } List connectedDevices = assistant.getConnectedDevices(); CachedBluetoothDeviceManager cacheManager = localBtManager.getCachedDeviceManager(); for (BluetoothDevice device : connectedDevices) { @@ -69,7 +76,7 @@ public class AudioSharingUtils { Log.d(TAG, "Skip device due to not being cached: " + device.getAnonymizedAddress()); continue; } - int groupId = cachedDevice.getGroupId(); + int groupId = getGroupId(cachedDevice); if (groupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { Log.d( TAG, @@ -105,9 +112,6 @@ public class AudioSharingUtils { Map> groupedConnectedDevices, boolean filterByInSharing) { List orderedDevices = new ArrayList<>(); - LocalBluetoothLeBroadcastAssistant assistant = - localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile(); - if (assistant == null) return orderedDevices; for (List devices : groupedConnectedDevices.values()) { CachedBluetoothDevice leadDevice = null; for (CachedBluetoothDevice device : devices) { @@ -191,7 +195,7 @@ public class AudioSharingUtils { CachedBluetoothDevice cachedDevice) { return new AudioSharingDeviceItem( cachedDevice.getName(), - cachedDevice.getGroupId(), + getGroupId(cachedDevice), isActiveLeAudioDevice(cachedDevice)); } @@ -204,19 +208,36 @@ public class AudioSharingUtils { */ public static boolean hasBroadcastSource( CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager) { + if (localBtManager == 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 hasBroadcastSource due to assistant profile is null"); return false; } List sourceList = assistant.getAllSources(cachedDevice.getDevice()); - if (!sourceList.isEmpty()) return true; + if (!sourceList.isEmpty()) { + Log.d( + TAG, + "Lead device has broadcast source, device = " + + cachedDevice.getDevice().getAnonymizedAddress()); + return true; + } // Return true if member device is in broadcast. for (CachedBluetoothDevice device : cachedDevice.getMemberDevice()) { List list = assistant.getAllSources(device.getDevice()); - if (!list.isEmpty()) return true; + if (!list.isEmpty()) { + Log.d( + TAG, + "Member device has broadcast source, device = " + + device.getDevice().getAnonymizedAddress()); + return true; + } } return false; } @@ -257,8 +278,8 @@ public class AudioSharingUtils { /** Toast message on main thread. */ public static void toastMessage(Context context, String message) { - ThreadUtils.postOnMainThread( - () -> Toast.makeText(context, message, Toast.LENGTH_LONG).show()); + context.getMainExecutor() + .execute(() -> Toast.makeText(context, message, Toast.LENGTH_LONG).show()); } /** Returns if the le audio sharing is enabled. */ @@ -273,7 +294,10 @@ public class AudioSharingUtils { /** Automatically update active device if needed. */ public static void updateActiveDeviceIfNeeded(LocalBluetoothManager localBtManager) { - if (localBtManager == null) return; + if (localBtManager == null) { + Log.d(TAG, "Skip updateActiveDeviceIfNeeded due to bt manager is null"); + return; + } Map> groupedConnectedDevices = fetchConnectedDevicesByGroupId(localBtManager); List devicesInSharing = @@ -283,6 +307,7 @@ public class AudioSharingUtils { List devices = BluetoothAdapter.getDefaultAdapter().getMostRecentlyConnectedDevices(); CachedBluetoothDevice targetDevice = null; + // Find the earliest connected device in sharing session. int targetDeviceIdx = -1; for (CachedBluetoothDevice device : devicesInSharing) { if (devices.contains(device.getDevice())) { @@ -299,6 +324,14 @@ public class AudioSharingUtils { "updateActiveDeviceIfNeeded, set active device: " + targetDevice.getDevice().getAnonymizedAddress()); targetDevice.setActive(); + } else { + Log.d( + TAG, + "updateActiveDeviceIfNeeded, skip set active device: " + + (targetDevice == null + ? "null" + : (targetDevice.getDevice().getAnonymizedAddress() + + " is already active"))); } } @@ -312,9 +345,38 @@ public class AudioSharingUtils { /** Stops the latest broadcast. */ public static void stopBroadcasting(LocalBluetoothManager manager) { - if (manager == null) return; + if (manager == null) { + Log.d(TAG, "Skip stop broadcasting due to bt manager is null"); + return; + } LocalBluetoothLeBroadcast broadcast = manager.getProfileManager().getLeAudioBroadcastProfile(); + if (broadcast == null) { + Log.d(TAG, "Skip stop broadcasting due to broadcast profile is null"); + } broadcast.stopBroadcast(broadcast.getLatestBroadcastId()); } + + /** + * Get CSIP group id for {@link CachedBluetoothDevice}. + * + *

If CachedBluetoothDevice#getGroupId is invalid, fetch group id from + * LeAudioProfile#getGroupId. + */ + public static int getGroupId(CachedBluetoothDevice cachedDevice) { + int groupId = cachedDevice.getGroupId(); + String anonymizedAddress = cachedDevice.getDevice().getAnonymizedAddress(); + if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + Log.d(TAG, "getGroupId by CSIP profile for device: " + anonymizedAddress); + return groupId; + } + for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) { + if (profile instanceof LeAudioProfile) { + Log.d(TAG, "getGroupId by LEA profile for device: " + anonymizedAddress); + return ((LeAudioProfile) profile).getGroupId(cachedDevice.getDevice()); + } + } + Log.d(TAG, "getGroupId return invalid id for device: " + anonymizedAddress); + return BluetoothCsipSetCoordinator.GROUP_ID_INVALID; + } }