Loading src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +163 −116 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ 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.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.List; Loading Loading @@ -260,6 +263,9 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro return; } mLocalBtManager.getEventManager().registerCallback(this); if (DEBUG) { Log.d(TAG, "onStart() Register callbacks for broadcast and assistant."); } mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback); mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mBluetoothDeviceUpdater.registerCallback(); Loading @@ -281,15 +287,11 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro return; } mLocalBtManager.getEventManager().unregisterCallback(this); // TODO: verify the reason for failing to unregister try { if (DEBUG) { 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()); } mBluetoothDeviceUpdater.unregisterCallback(); } Loading Loading @@ -358,6 +360,28 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro "Ignore onProfileConnectionStateChanged, no broadcast or assistant supported"); 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); // For eligible (LE audio) remote device, we only check its connected LE audio profile. if (isLeAudioSupported && bluetoothProfile != BluetoothProfile.LE_AUDIO) { Loading @@ -384,14 +408,26 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro } if (!isLeAudioSupported) { // Handle connected ineligible (non LE audio) remote device handleOnProfileStateChangedForNonLeAudioDevice(cachedDevice); } else { // Handle connected eligible (LE audio) remote device handleOnProfileStateChangedForLeAudioDevice(cachedDevice); } } private void handleOnProfileStateChangedForNonLeAudioDevice( @NonNull CachedBluetoothDevice cachedDevice) { if (isBroadcasting()) { // Show stop audio sharing dialog when an ineligible (non LE audio) remote device // connected during a sharing session. ThreadUtils.postOnMainThread( () -> { 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) { Loading @@ -401,11 +437,26 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro + " sharing session"); } } } else { } private void handleOnProfileStateChangedForLeAudioDevice( @NonNull CachedBluetoothDevice cachedDevice) { Map<Integer, List<CachedBluetoothDevice>> groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(mLocalBtManager); // Handle connected eligible (LE audio) remote device if (isBroadcasting()) { if (groupedDevices.containsKey(cachedDevice.getGroupId()) && groupedDevices.get(cachedDevice.getGroupId()).stream() .anyMatch( device -> AudioSharingUtils.hasBroadcastSource( device, mLocalBtManager))) { Log.d( 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 = Loading @@ -414,6 +465,8 @@ 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( () -> { closeOpeningDialogs(); AudioSharingDisconnectDialogFragment.show( mFragment, Loading @@ -421,12 +474,16 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro 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.getAllSources( device.getDevice())) { mAssistant.removeSource( device.getDevice(), source.getSourceId()); device.getDevice(), source.getSourceId()); } } } // Add current broadcast to the latest connected device Loading @@ -435,9 +492,12 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro 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, Loading @@ -450,21 +510,23 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro 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. // 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. // 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, Loading @@ -480,25 +542,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro } mBroadcast.startBroadcast("test", null); }); }); } } } } /** * 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 boolean isLeAudioSupported(CachedBluetoothDevice cachedDevice) { return cachedDevice.getProfiles().stream() Loading Loading
src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +163 −116 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ 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.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.List; Loading Loading @@ -260,6 +263,9 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro return; } mLocalBtManager.getEventManager().registerCallback(this); if (DEBUG) { Log.d(TAG, "onStart() Register callbacks for broadcast and assistant."); } mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback); mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mBluetoothDeviceUpdater.registerCallback(); Loading @@ -281,15 +287,11 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro return; } mLocalBtManager.getEventManager().unregisterCallback(this); // TODO: verify the reason for failing to unregister try { if (DEBUG) { 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()); } mBluetoothDeviceUpdater.unregisterCallback(); } Loading Loading @@ -358,6 +360,28 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro "Ignore onProfileConnectionStateChanged, no broadcast or assistant supported"); 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); // For eligible (LE audio) remote device, we only check its connected LE audio profile. if (isLeAudioSupported && bluetoothProfile != BluetoothProfile.LE_AUDIO) { Loading @@ -384,14 +408,26 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro } if (!isLeAudioSupported) { // Handle connected ineligible (non LE audio) remote device handleOnProfileStateChangedForNonLeAudioDevice(cachedDevice); } else { // Handle connected eligible (LE audio) remote device handleOnProfileStateChangedForLeAudioDevice(cachedDevice); } } private void handleOnProfileStateChangedForNonLeAudioDevice( @NonNull CachedBluetoothDevice cachedDevice) { if (isBroadcasting()) { // Show stop audio sharing dialog when an ineligible (non LE audio) remote device // connected during a sharing session. ThreadUtils.postOnMainThread( () -> { 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) { Loading @@ -401,11 +437,26 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro + " sharing session"); } } } else { } private void handleOnProfileStateChangedForLeAudioDevice( @NonNull CachedBluetoothDevice cachedDevice) { Map<Integer, List<CachedBluetoothDevice>> groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(mLocalBtManager); // Handle connected eligible (LE audio) remote device if (isBroadcasting()) { if (groupedDevices.containsKey(cachedDevice.getGroupId()) && groupedDevices.get(cachedDevice.getGroupId()).stream() .anyMatch( device -> AudioSharingUtils.hasBroadcastSource( device, mLocalBtManager))) { Log.d( 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 = Loading @@ -414,6 +465,8 @@ 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( () -> { closeOpeningDialogs(); AudioSharingDisconnectDialogFragment.show( mFragment, Loading @@ -421,12 +474,16 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro 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.getAllSources( device.getDevice())) { mAssistant.removeSource( device.getDevice(), source.getSourceId()); device.getDevice(), source.getSourceId()); } } } // Add current broadcast to the latest connected device Loading @@ -435,9 +492,12 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro 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, Loading @@ -450,21 +510,23 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro 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. // 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. // 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, Loading @@ -480,25 +542,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro } mBroadcast.startBroadcast("test", null); }); }); } } } } /** * 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 boolean isLeAudioSupported(CachedBluetoothDevice cachedDevice) { return cachedDevice.getProfiles().stream() Loading