[Audiosharing] Hide / show audio streams category.
Only show when there is an active LE buds connecting, and the source is
not currently broadcasting.
Bug: 308368124
Test: Manual
Change-Id: I2cc172a66648901ac8a7e49c5aac734b6bbc7e33
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
index 9ebe26d..21f1c0e 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBasePreferenceController.java
@@ -64,7 +64,7 @@
mPreference.setVisible(isVisible);
}
- private boolean isBroadcasting() {
+ protected boolean isBroadcasting() {
return mBroadcast != null && mBroadcast.isEnabled(null);
}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
index cf5881b..7f90ceb 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
@@ -22,6 +22,7 @@
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.widget.SettingsMainSwitchBar;
@@ -34,6 +35,7 @@
private AudioSharingDeviceVolumeGroupController mAudioSharingDeviceVolumeGroupController;
private CallsAndAlarmsPreferenceController mCallsAndAlarmsPreferenceController;
private AudioSharingNamePreferenceController mAudioSharingNamePreferenceController;
+ private AudioStreamsCategoryController mAudioStreamsCategoryController;
public AudioSharingDashboardFragment() {
super();
@@ -73,6 +75,7 @@
mCallsAndAlarmsPreferenceController = use(CallsAndAlarmsPreferenceController.class);
mCallsAndAlarmsPreferenceController.init(this);
mAudioSharingNamePreferenceController = use(AudioSharingNamePreferenceController.class);
+ mAudioStreamsCategoryController = use(AudioStreamsCategoryController.class);
}
@Override
@@ -98,5 +101,6 @@
mAudioSharingDeviceVolumeGroupController.updateVisibility(isVisible);
mCallsAndAlarmsPreferenceController.updateVisibility(isVisible);
mAudioSharingNamePreferenceController.updateVisibility(isVisible);
+ mAudioStreamsCategoryController.updateVisibility(isVisible);
}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index 53e095b..1a50496 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -34,6 +34,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
public class AudioSharingUtils {
@@ -229,6 +230,31 @@
return false;
}
+ /**
+ * Retrieves the one and only active Bluetooth LE Audio sink device, regardless if the device is
+ * currently in an audio sharing session.
+ *
+ * @param manager The LocalBluetoothManager instance used to fetch connected devices.
+ * @return An Optional containing the active LE Audio device, or an empty Optional if not found.
+ */
+ public static Optional<CachedBluetoothDevice> getActiveSinkOnAssistant(
+ LocalBluetoothManager manager) {
+ if (manager == null) {
+ Log.w(TAG, "getActiveSinksOnAssistant(): LocalBluetoothManager is null!");
+ return Optional.empty();
+ }
+ var groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(manager);
+ var leadDevices =
+ AudioSharingUtils.buildOrderedConnectedLeadDevices(manager, groupedDevices, false);
+
+ if (!leadDevices.isEmpty() && AudioSharingUtils.isActiveLeAudioDevice(leadDevices.get(0))) {
+ return Optional.of(leadDevices.get(0));
+ } else {
+ Log.w(TAG, "getActiveSinksOnAssistant(): No active lead device!");
+ }
+ return Optional.empty();
+ }
+
/** Toast message on main thread. */
public static void toastMessage(Context context, String message) {
ThreadUtils.postOnMainThread(
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdater.java
index cf79596..0d3b1b1 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdater.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsActiveDeviceSummaryUpdater.java
@@ -30,8 +30,6 @@
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.utils.ThreadUtils;
-import java.util.Optional;
-
public class AudioStreamsActiveDeviceSummaryUpdater implements BluetoothCallback {
private static final String TAG = "AudioStreamsActiveDeviceSummaryUpdater";
private static final boolean DEBUG = BluetoothUtils.D;
@@ -82,31 +80,13 @@
}
private String getSummary() {
- var activeSink = getActiveSinkOnAssistant(mBluetoothManager);
+ var activeSink = AudioSharingUtils.getActiveSinkOnAssistant(mBluetoothManager);
if (activeSink.isEmpty()) {
return "No active LE Audio device";
}
return activeSink.get().getName();
}
- private static Optional<CachedBluetoothDevice> getActiveSinkOnAssistant(
- LocalBluetoothManager manager) {
- if (manager == null) {
- Log.w(TAG, "getActiveSinksOnAssistant(): LocalBluetoothManager is null!");
- return Optional.empty();
- }
- var groupedDevices = AudioSharingUtils.fetchConnectedDevicesByGroupId(manager);
- var leadDevices =
- AudioSharingUtils.buildOrderedConnectedLeadDevices(manager, groupedDevices, false);
-
- if (!leadDevices.isEmpty() && AudioSharingUtils.isActiveLeAudioDevice(leadDevices.get(0))) {
- return Optional.of(leadDevices.get(0));
- } else {
- Log.w(TAG, "getActiveSinksOnAssistant(): No active lead device!");
- }
- return Optional.empty();
- }
-
/** Interface definition for a callback to be invoked when the summary has been changed. */
interface OnSummaryChangeListener {
/**
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java
index 84a7be9..f80fdab 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java
@@ -16,15 +16,64 @@
package com.android.settings.connecteddevice.audiosharing.audiostreams;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothProfile;
import android.content.Context;
+import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.lifecycle.DefaultLifecycleObserver;
+import androidx.lifecycle.LifecycleOwner;
+
+import com.android.settings.bluetooth.Utils;
+import com.android.settings.connecteddevice.audiosharing.AudioSharingBasePreferenceController;
+import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
import com.android.settings.flags.Flags;
-import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.utils.ThreadUtils;
-public class AudioStreamsCategoryController extends PreferenceCategoryController {
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+public class AudioStreamsCategoryController extends AudioSharingBasePreferenceController
+ implements DefaultLifecycleObserver {
+ private static final String TAG = "AudioStreamsCategoryController";
+ private static final boolean DEBUG = BluetoothUtils.D;
+ private final LocalBluetoothManager mLocalBtManager;
+ private final Executor mExecutor;
+ private final BluetoothCallback mBluetoothCallback =
+ new BluetoothCallback() {
+ @Override
+ public void onActiveDeviceChanged(
+ @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) {
+ if (bluetoothProfile == BluetoothProfile.LE_AUDIO) {
+ updateVisibility(isBroadcasting());
+ }
+ }
+ };
public AudioStreamsCategoryController(Context context, String key) {
super(context, key);
+ mLocalBtManager = Utils.getLocalBtManager(mContext);
+ mExecutor = Executors.newSingleThreadExecutor();
+ }
+
+ @Override
+ public void onStart(@NonNull LifecycleOwner owner) {
+ if (mLocalBtManager != null) {
+ mLocalBtManager.getEventManager().registerCallback(mBluetoothCallback);
+ }
+ updateVisibility(isBroadcasting());
+ }
+
+ @Override
+ public void onStop(@NonNull LifecycleOwner owner) {
+ if (mLocalBtManager != null) {
+ mLocalBtManager.getEventManager().unregisterCallback(mBluetoothCallback);
+ }
}
@Override
@@ -33,4 +82,23 @@
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
+
+ @Override
+ public void updateVisibility(boolean isBroadcasting) {
+ mExecutor.execute(
+ () -> {
+ boolean hasActiveLe =
+ AudioSharingUtils.getActiveSinkOnAssistant(mLocalBtManager).isPresent();
+ if (DEBUG) {
+ Log.d(
+ TAG,
+ "updateVisibility() isBroadcasting : "
+ + isBroadcasting
+ + " hasActiveLe : "
+ + hasActiveLe);
+ }
+ ThreadUtils.postOnMainThread(
+ () -> super.updateVisibility(hasActiveLe && !isBroadcasting));
+ });
+ }
}