[Audiosharing] Update device list when primary buds change

Test: atest
Bug: 399161206
Flag: com.android.settingslib.flags.enable_le_audio_sharing
Change-Id: Ic99e14492456bd9901c71fa3cec3f894b6ec63e6
This commit is contained in:
Yiyi Shen
2025-03-11 17:36:06 +08:00
parent f3f3db1d91
commit 1b00e97a5c
2 changed files with 50 additions and 1 deletions

View File

@@ -26,9 +26,14 @@ import android.bluetooth.BluetoothLeBroadcastAssistant;
import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.ContentObserver;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -87,6 +92,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
@Nullable private final LocalBluetoothProfileManager mProfileManager; @Nullable private final LocalBluetoothProfileManager mProfileManager;
@Nullable private final LocalBluetoothLeBroadcast mBroadcast; @Nullable private final LocalBluetoothLeBroadcast mBroadcast;
@Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant; @Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant;
@Nullable private final ContentResolver mContentResolver;
private final Executor mExecutor; private final Executor mExecutor;
private final MetricsFeatureProvider mMetricsFeatureProvider; private final MetricsFeatureProvider mMetricsFeatureProvider;
@Nullable private PreferenceGroup mPreferenceGroup; @Nullable private PreferenceGroup mPreferenceGroup;
@@ -187,6 +193,17 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
@NonNull BluetoothLeBroadcastReceiveState state) {} @NonNull BluetoothLeBroadcastReceiveState state) {}
}; };
@VisibleForTesting
ContentObserver mSettingsObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange) {
Log.d(TAG, "onChange, primary group id has been changed, refresh list");
if (mBluetoothDeviceUpdater != null) {
mBluetoothDeviceUpdater.refreshPreference();
}
}
};
public AudioSharingDevicePreferenceController(Context context) { public AudioSharingDevicePreferenceController(Context context) {
super(context, KEY); super(context, KEY);
mBtManager = Utils.getLocalBtManager(mContext); mBtManager = Utils.getLocalBtManager(mContext);
@@ -198,6 +215,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
mProfileManager == null mProfileManager == null
? null ? null
: mProfileManager.getLeAudioBroadcastAssistantProfile(); : mProfileManager.getLeAudioBroadcastAssistantProfile();
mContentResolver = context.getContentResolver();
mExecutor = Executors.newSingleThreadExecutor(); mExecutor = Executors.newSingleThreadExecutor();
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
} }
@@ -217,6 +235,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
if (mEventManager == null if (mEventManager == null
|| mAssistant == null || mAssistant == null
|| mDialogHandler == null || mDialogHandler == null
|| mContentResolver == null
|| mBluetoothDeviceUpdater == null) { || mBluetoothDeviceUpdater == null) {
Log.d(TAG, "Skip onStart(), profile is not ready."); Log.d(TAG, "Skip onStart(), profile is not ready.");
return; return;
@@ -225,6 +244,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
mEventManager.registerCallback(this); mEventManager.registerCallback(this);
mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
mDialogHandler.registerCallbacks(mExecutor); mDialogHandler.registerCallbacks(mExecutor);
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mSettingsObserver);
mBluetoothDeviceUpdater.registerCallback(); mBluetoothDeviceUpdater.registerCallback();
mBluetoothDeviceUpdater.refreshPreference(); mBluetoothDeviceUpdater.refreshPreference();
mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext)); mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext));
@@ -245,6 +268,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
if (mEventManager == null if (mEventManager == null
|| mAssistant == null || mAssistant == null
|| mDialogHandler == null || mDialogHandler == null
|| mContentResolver == null
|| mBluetoothDeviceUpdater == null) { || mBluetoothDeviceUpdater == null) {
Log.d(TAG, "Skip onStop(), profile is not ready."); Log.d(TAG, "Skip onStop(), profile is not ready.");
return; return;
@@ -253,6 +277,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
mEventManager.unregisterCallback(this); mEventManager.unregisterCallback(this);
mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback); mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
mDialogHandler.unregisterCallbacks(); mDialogHandler.unregisterCallbacks();
mContentResolver.unregisterContentObserver(mSettingsObserver);
mBluetoothDeviceUpdater.unregisterCallback(); mBluetoothDeviceUpdater.unregisterCallback();
}); });
} }

View File

@@ -45,6 +45,7 @@ import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothStatusCodes;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@@ -79,6 +80,7 @@ import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.BluetoothEventManager; import com.android.settingslib.bluetooth.BluetoothEventManager;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HeadsetProfile;
@@ -144,6 +146,7 @@ public class AudioSharingDevicePreferenceControllerTest {
@Mock private LeAudioProfile mLeAudioProfile; @Mock private LeAudioProfile mLeAudioProfile;
@Mock private A2dpProfile mA2dpProfile; @Mock private A2dpProfile mA2dpProfile;
@Mock private HeadsetProfile mHeadsetProfile; @Mock private HeadsetProfile mHeadsetProfile;
@Mock private ContentResolver mContentResolver;
private Context mContext; private Context mContext;
private AudioSharingDevicePreferenceController mController; private AudioSharingDevicePreferenceController mController;
@@ -156,7 +159,7 @@ public class AudioSharingDevicePreferenceControllerTest {
@Before @Before
public void setUp() { public void setUp() {
mContext = ApplicationProvider.getApplicationContext(); mContext = spy(ApplicationProvider.getApplicationContext());
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
mShadowBluetoothAdapter.setEnabled(true); mShadowBluetoothAdapter.setEnabled(true);
mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
@@ -185,6 +188,7 @@ public class AudioSharingDevicePreferenceControllerTest {
when(mA2dpProfile.getProfileId()).thenReturn(BluetoothProfile.A2DP); when(mA2dpProfile.getProfileId()).thenReturn(BluetoothProfile.A2DP);
when(mLeAudioProfile.getProfileId()).thenReturn(BluetoothProfile.LE_AUDIO); when(mLeAudioProfile.getProfileId()).thenReturn(BluetoothProfile.LE_AUDIO);
when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true); when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mScreen.getContext()).thenReturn(mContext); when(mScreen.getContext()).thenReturn(mContext);
mPreferenceGroup = spy(new PreferenceCategory(mContext)); mPreferenceGroup = spy(new PreferenceCategory(mContext));
doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager(); doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager();
@@ -211,6 +215,12 @@ public class AudioSharingDevicePreferenceControllerTest {
verify(mAssistant, never()) verify(mAssistant, never())
.registerServiceCallBack( .registerServiceCallBack(
any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
verify(mContentResolver, never())
.registerContentObserver(
Settings.Secure.getUriFor(
BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mController.mSettingsObserver);
verify(mBluetoothDeviceUpdater, never()).registerCallback(); verify(mBluetoothDeviceUpdater, never()).registerCallback();
verify(mBluetoothDeviceUpdater, never()).refreshPreference(); verify(mBluetoothDeviceUpdater, never()).refreshPreference();
} }
@@ -224,6 +234,12 @@ public class AudioSharingDevicePreferenceControllerTest {
verify(mAssistant) verify(mAssistant)
.registerServiceCallBack( .registerServiceCallBack(
any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class));
verify(mContentResolver)
.registerContentObserver(
Settings.Secure.getUriFor(
BluetoothUtils.getPrimaryGroupIdUriForBroadcast()),
false,
mController.mSettingsObserver);
verify(mBluetoothDeviceUpdater).registerCallback(); verify(mBluetoothDeviceUpdater).registerCallback();
verify(mBluetoothDeviceUpdater).refreshPreference(); verify(mBluetoothDeviceUpdater).refreshPreference();
} }
@@ -236,6 +252,7 @@ public class AudioSharingDevicePreferenceControllerTest {
verify(mDialogHandler, never()).unregisterCallbacks(); verify(mDialogHandler, never()).unregisterCallbacks();
verify(mAssistant, never()) verify(mAssistant, never())
.unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
verify(mContentResolver, never()).unregisterContentObserver(mController.mSettingsObserver);
verify(mBluetoothDeviceUpdater, never()).unregisterCallback(); verify(mBluetoothDeviceUpdater, never()).unregisterCallback();
} }
@@ -247,6 +264,7 @@ public class AudioSharingDevicePreferenceControllerTest {
verify(mDialogHandler).unregisterCallbacks(); verify(mDialogHandler).unregisterCallbacks();
verify(mAssistant) verify(mAssistant)
.unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class));
verify(mContentResolver).unregisterContentObserver(mController.mSettingsObserver);
verify(mBluetoothDeviceUpdater).unregisterCallback(); verify(mBluetoothDeviceUpdater).unregisterCallback();
} }
@@ -485,6 +503,12 @@ public class AudioSharingDevicePreferenceControllerTest {
verifyNoInteractions(mDialogHandler); verifyNoInteractions(mDialogHandler);
} }
@Test
public void onFallbackDeviceChanged_updateSummary() {
mController.mSettingsObserver.onChange(true);
verify(mBluetoothDeviceUpdater).refreshPreference();
}
@Test @Test
@EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
public void handleDeviceClickFromIntent_noDevice_doNothing() { public void handleDeviceClickFromIntent_noDevice_doNothing() {