[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
This commit is contained in:
chelseahao
2023-11-23 15:42:28 +08:00
committed by Chelsea Hao
parent 40cc58f5a1
commit 78a667e7ca
5 changed files with 102 additions and 24 deletions

View File

@@ -64,7 +64,7 @@ public abstract class AudioSharingBasePreferenceController extends BasePreferenc
mPreference.setVisible(isVisible); mPreference.setVisible(isVisible);
} }
private boolean isBroadcasting() { protected boolean isBroadcasting() {
return mBroadcast != null && mBroadcast.isEnabled(null); return mBroadcast != null && mBroadcast.isEnabled(null);
} }
} }

View File

@@ -22,6 +22,7 @@ import android.os.Bundle;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsCategoryController;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.widget.SettingsMainSwitchBar; import com.android.settings.widget.SettingsMainSwitchBar;
@@ -34,6 +35,7 @@ public class AudioSharingDashboardFragment extends DashboardFragment
private AudioSharingDeviceVolumeGroupController mAudioSharingDeviceVolumeGroupController; private AudioSharingDeviceVolumeGroupController mAudioSharingDeviceVolumeGroupController;
private CallsAndAlarmsPreferenceController mCallsAndAlarmsPreferenceController; private CallsAndAlarmsPreferenceController mCallsAndAlarmsPreferenceController;
private AudioSharingNamePreferenceController mAudioSharingNamePreferenceController; private AudioSharingNamePreferenceController mAudioSharingNamePreferenceController;
private AudioStreamsCategoryController mAudioStreamsCategoryController;
public AudioSharingDashboardFragment() { public AudioSharingDashboardFragment() {
super(); super();
@@ -73,6 +75,7 @@ public class AudioSharingDashboardFragment extends DashboardFragment
mCallsAndAlarmsPreferenceController = use(CallsAndAlarmsPreferenceController.class); mCallsAndAlarmsPreferenceController = use(CallsAndAlarmsPreferenceController.class);
mCallsAndAlarmsPreferenceController.init(this); mCallsAndAlarmsPreferenceController.init(this);
mAudioSharingNamePreferenceController = use(AudioSharingNamePreferenceController.class); mAudioSharingNamePreferenceController = use(AudioSharingNamePreferenceController.class);
mAudioStreamsCategoryController = use(AudioStreamsCategoryController.class);
} }
@Override @Override
@@ -98,5 +101,6 @@ public class AudioSharingDashboardFragment extends DashboardFragment
mAudioSharingDeviceVolumeGroupController.updateVisibility(isVisible); mAudioSharingDeviceVolumeGroupController.updateVisibility(isVisible);
mCallsAndAlarmsPreferenceController.updateVisibility(isVisible); mCallsAndAlarmsPreferenceController.updateVisibility(isVisible);
mAudioSharingNamePreferenceController.updateVisibility(isVisible); mAudioSharingNamePreferenceController.updateVisibility(isVisible);
mAudioStreamsCategoryController.updateVisibility(isVisible);
} }
} }

View File

@@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class AudioSharingUtils { public class AudioSharingUtils {
@@ -229,6 +230,31 @@ public class AudioSharingUtils {
return false; 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. */ /** Toast message on main thread. */
public static void toastMessage(Context context, String message) { public static void toastMessage(Context context, String message) {
ThreadUtils.postOnMainThread( ThreadUtils.postOnMainThread(

View File

@@ -30,8 +30,6 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.utils.ThreadUtils; import com.android.settingslib.utils.ThreadUtils;
import java.util.Optional;
public class AudioStreamsActiveDeviceSummaryUpdater implements BluetoothCallback { public class AudioStreamsActiveDeviceSummaryUpdater implements BluetoothCallback {
private static final String TAG = "AudioStreamsActiveDeviceSummaryUpdater"; private static final String TAG = "AudioStreamsActiveDeviceSummaryUpdater";
private static final boolean DEBUG = BluetoothUtils.D; private static final boolean DEBUG = BluetoothUtils.D;
@@ -82,31 +80,13 @@ public class AudioStreamsActiveDeviceSummaryUpdater implements BluetoothCallback
} }
private String getSummary() { private String getSummary() {
var activeSink = getActiveSinkOnAssistant(mBluetoothManager); var activeSink = AudioSharingUtils.getActiveSinkOnAssistant(mBluetoothManager);
if (activeSink.isEmpty()) { if (activeSink.isEmpty()) {
return "No active LE Audio device"; return "No active LE Audio device";
} }
return activeSink.get().getName(); 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 definition for a callback to be invoked when the summary has been changed. */
interface OnSummaryChangeListener { interface OnSummaryChangeListener {
/** /**

View File

@@ -16,15 +16,64 @@
package com.android.settings.connecteddevice.audiosharing.audiostreams; package com.android.settings.connecteddevice.audiosharing.audiostreams;
import android.annotation.Nullable;
import android.bluetooth.BluetoothProfile;
import android.content.Context; 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.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) { public AudioStreamsCategoryController(Context context, String key) {
super(context, 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 @Override
@@ -33,4 +82,23 @@ public class AudioStreamsCategoryController extends PreferenceCategoryController
? AVAILABLE ? AVAILABLE
: UNSUPPORTED_ON_DEVICE; : 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));
});
}
} }