Merge "[Audiosharing] Move time consuming work to background." into main

This commit is contained in:
Yiyi Shen
2023-12-14 07:30:55 +00:00
committed by Android (Google) Code Review

View File

@@ -47,6 +47,9 @@ import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.utils.ThreadUtils;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -260,6 +263,9 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
return; return;
} }
mLocalBtManager.getEventManager().registerCallback(this); mLocalBtManager.getEventManager().registerCallback(this);
if (DEBUG) {
Log.d(TAG, "onStart() Register callbacks for broadcast and assistant.");
}
mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback); mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
mBluetoothDeviceUpdater.registerCallback(); mBluetoothDeviceUpdater.registerCallback();
@@ -281,15 +287,11 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
return; return;
} }
mLocalBtManager.getEventManager().unregisterCallback(this); mLocalBtManager.getEventManager().unregisterCallback(this);
// TODO: verify the reason for failing to unregister if (DEBUG) {
try { Log.d(TAG, "onStop() Unregister callbacks for broadcast and assistant.");
mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
} catch (IllegalArgumentException e) {
Log.e(
TAG,
"Fail to unregister broadcast or assistant callback due to " + e.getMessage());
} }
mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
mBluetoothDeviceUpdater.unregisterCallback(); mBluetoothDeviceUpdater.unregisterCallback();
} }
@@ -358,6 +360,28 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
"Ignore onProfileConnectionStateChanged, no broadcast or assistant supported"); "Ignore onProfileConnectionStateChanged, no broadcast or assistant supported");
return; return;
} }
var unused =
ThreadUtils.postOnBackgroundThread(
() -> handleOnProfileStateChanged(cachedDevice, bluetoothProfile));
}
/**
* Initialize the controller.
*
* @param fragment The fragment to provide the context and metrics category for {@link
* AudioSharingBluetoothDeviceUpdater} and provide the host for dialogs.
*/
public void init(DashboardFragment fragment) {
mFragment = fragment;
mBluetoothDeviceUpdater =
new AudioSharingBluetoothDeviceUpdater(
fragment.getContext(),
AudioSharingDevicePreferenceController.this,
fragment.getMetricsCategory());
}
private void handleOnProfileStateChanged(
@NonNull CachedBluetoothDevice cachedDevice, int bluetoothProfile) {
boolean isLeAudioSupported = isLeAudioSupported(cachedDevice); boolean isLeAudioSupported = isLeAudioSupported(cachedDevice);
// For eligible (LE audio) remote device, we only check its connected LE audio profile. // For eligible (LE audio) remote device, we only check its connected LE audio profile.
if (isLeAudioSupported && bluetoothProfile != BluetoothProfile.LE_AUDIO) { if (isLeAudioSupported && bluetoothProfile != BluetoothProfile.LE_AUDIO) {
@@ -384,120 +408,143 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
} }
if (!isLeAudioSupported) { if (!isLeAudioSupported) {
// Handle connected ineligible (non LE audio) remote device // Handle connected ineligible (non LE audio) remote device
if (isBroadcasting()) { handleOnProfileStateChangedForNonLeAudioDevice(cachedDevice);
// Show stop audio sharing dialog when an ineligible (non LE audio) remote device
// connected during a sharing session.
closeOpeningDialogs();
AudioSharingStopDialogFragment.show(
mFragment,
cachedDevice.getName(),
() -> mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId()));
} else {
// Do nothing for ineligible (non LE audio) remote device when no sharing session.
if (DEBUG) {
Log.d(
TAG,
"Ignore onProfileConnectionStateChanged for non LE audio without"
+ " sharing session");
}
}
} else { } else {
Map<Integer, List<CachedBluetoothDevice>> groupedDevices =
AudioSharingUtils.fetchConnectedDevicesByGroupId(mLocalBtManager);
// Handle connected eligible (LE audio) remote device // Handle connected eligible (LE audio) remote device
if (isBroadcasting()) { handleOnProfileStateChangedForLeAudioDevice(cachedDevice);
// Show audio sharing switch or join dialog according to device count in the sharing }
// session. }
ArrayList<AudioSharingDeviceItem> deviceItemsInSharingSession =
AudioSharingUtils.buildOrderedConnectedLeadAudioSharingDeviceItem( private void handleOnProfileStateChangedForNonLeAudioDevice(
mLocalBtManager, groupedDevices, /* filterByInSharing= */ true); @NonNull CachedBluetoothDevice cachedDevice) {
// Show audio sharing switch dialog when the third eligible (LE audio) remote device if (isBroadcasting()) {
// connected during a sharing session. // Show stop audio sharing dialog when an ineligible (non LE audio) remote device
if (deviceItemsInSharingSession.size() >= 2) { // connected during a sharing session.
closeOpeningDialogs(); ThreadUtils.postOnMainThread(
AudioSharingDisconnectDialogFragment.show( () -> {
mFragment, closeOpeningDialogs();
deviceItemsInSharingSession, AudioSharingStopDialogFragment.show(
cachedDevice.getName(), mFragment,
(AudioSharingDeviceItem item) -> { cachedDevice.getName(),
// Remove all sources from the device user clicked () -> mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId()));
for (CachedBluetoothDevice device : });
groupedDevices.get(item.getGroupId())) { } else {
for (BluetoothLeBroadcastReceiveState source : // Do nothing for ineligible (non LE audio) remote device when no sharing session.
mAssistant.getAllSources(device.getDevice())) { if (DEBUG) {
mAssistant.removeSource( Log.d(
device.getDevice(), source.getSourceId()); TAG,
} "Ignore onProfileConnectionStateChanged for non LE audio without"
} + " sharing session");
// Add current broadcast to the latest connected device
mAssistant.addSource(
cachedDevice.getDevice(),
mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
/* isGroupOp= */ true);
});
} else {
// Show audio sharing join dialog when the first or second eligible (LE audio)
// remote device connected during a sharing session.
closeOpeningDialogs();
AudioSharingJoinDialogFragment.show(
mFragment,
deviceItemsInSharingSession,
cachedDevice.getName(),
() -> {
// Add current broadcast to the latest connected device
mAssistant.addSource(
cachedDevice.getDevice(),
mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
/* isGroupOp= */ true);
});
}
} else {
ArrayList<AudioSharingDeviceItem> deviceItems = new ArrayList<>();
for (List<CachedBluetoothDevice> 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()) {
continue;
}
deviceItems.add(AudioSharingUtils.buildAudioSharingDeviceItem(device));
}
// Show audio sharing join dialog when the second eligible (LE audio) remote device
// connect and no sharing session.
if (deviceItems.size() == 1) {
closeOpeningDialogs();
AudioSharingJoinDialogFragment.show(
mFragment,
deviceItems,
cachedDevice.getName(),
() -> {
mTargetSinks = new ArrayList<>();
for (List<CachedBluetoothDevice> devices :
groupedDevices.values()) {
for (CachedBluetoothDevice device : devices) {
mTargetSinks.add(device.getDevice());
}
}
mBroadcast.startBroadcast("test", null);
});
}
} }
} }
} }
/** private void handleOnProfileStateChangedForLeAudioDevice(
* Initialize the controller. @NonNull CachedBluetoothDevice cachedDevice) {
* Map<Integer, List<CachedBluetoothDevice>> groupedDevices =
* @param fragment The fragment to provide the context and metrics category for {@link AudioSharingUtils.fetchConnectedDevicesByGroupId(mLocalBtManager);
* AudioSharingBluetoothDeviceUpdater} and provide the host for dialogs. if (isBroadcasting()) {
*/ if (groupedDevices.containsKey(cachedDevice.getGroupId())
public void init(DashboardFragment fragment) { && groupedDevices.get(cachedDevice.getGroupId()).stream()
mFragment = fragment; .anyMatch(
mBluetoothDeviceUpdater = device ->
new AudioSharingBluetoothDeviceUpdater( AudioSharingUtils.hasBroadcastSource(
fragment.getContext(), device, mLocalBtManager))) {
AudioSharingDevicePreferenceController.this, Log.d(
fragment.getMetricsCategory()); TAG,
"Automatically add another device within the same group to the sharing: "
+ cachedDevice.getDevice().getAnonymizedAddress());
addSourceToTargetDevices(ImmutableList.of(cachedDevice.getDevice()));
return;
}
// Show audio sharing switch or join dialog according to device count in the sharing
// session.
ArrayList<AudioSharingDeviceItem> deviceItemsInSharingSession =
AudioSharingUtils.buildOrderedConnectedLeadAudioSharingDeviceItem(
mLocalBtManager, groupedDevices, /* filterByInSharing= */ true);
// Show audio sharing switch dialog when the third eligible (LE audio) remote device
// connected during a sharing session.
if (deviceItemsInSharingSession.size() >= 2) {
ThreadUtils.postOnMainThread(
() -> {
closeOpeningDialogs();
AudioSharingDisconnectDialogFragment.show(
mFragment,
deviceItemsInSharingSession,
cachedDevice.getName(),
(AudioSharingDeviceItem item) -> {
// Remove all sources from the device user clicked
if (groupedDevices.containsKey(item.getGroupId())) {
for (CachedBluetoothDevice device :
groupedDevices.get(item.getGroupId())) {
for (BluetoothLeBroadcastReceiveState source :
mAssistant.getAllSources(
device.getDevice())) {
mAssistant.removeSource(
device.getDevice(),
source.getSourceId());
}
}
}
// Add current broadcast to the latest connected device
mAssistant.addSource(
cachedDevice.getDevice(),
mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
/* isGroupOp= */ true);
});
});
} else {
// Show audio sharing join dialog when the first or second eligible (LE audio)
// remote device connected during a sharing session.
ThreadUtils.postOnMainThread(
() -> {
closeOpeningDialogs();
AudioSharingJoinDialogFragment.show(
mFragment,
deviceItemsInSharingSession,
cachedDevice.getName(),
() -> {
// Add current broadcast to the latest connected device
mAssistant.addSource(
cachedDevice.getDevice(),
mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
/* isGroupOp= */ true);
});
});
}
} else {
ArrayList<AudioSharingDeviceItem> deviceItems = new ArrayList<>();
for (List<CachedBluetoothDevice> 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()) {
continue;
}
deviceItems.add(AudioSharingUtils.buildAudioSharingDeviceItem(device));
}
// Show audio sharing join dialog when the second eligible (LE audio) remote
// device connect and no sharing session.
if (deviceItems.size() == 1) {
ThreadUtils.postOnMainThread(
() -> {
closeOpeningDialogs();
AudioSharingJoinDialogFragment.show(
mFragment,
deviceItems,
cachedDevice.getName(),
() -> {
mTargetSinks = new ArrayList<>();
for (List<CachedBluetoothDevice> devices :
groupedDevices.values()) {
for (CachedBluetoothDevice device : devices) {
mTargetSinks.add(device.getDevice());
}
}
mBroadcast.startBroadcast("test", null);
});
});
}
}
} }
private boolean isLeAudioSupported(CachedBluetoothDevice cachedDevice) { private boolean isLeAudioSupported(CachedBluetoothDevice cachedDevice) {