From 1b00e97a5cd4d2d16fe680f7588de501ba2edbdf Mon Sep 17 00:00:00 2001 From: Yiyi Shen Date: Tue, 11 Mar 2025 17:36:06 +0800 Subject: [PATCH] [Audiosharing] Update device list when primary buds change Test: atest Bug: 399161206 Flag: com.android.settingslib.flags.enable_le_audio_sharing Change-Id: Ic99e14492456bd9901c71fa3cec3f894b6ec63e6 --- ...udioSharingDevicePreferenceController.java | 25 ++++++++++++++++++ ...SharingDevicePreferenceControllerTest.java | 26 ++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java index 68cb8226b7b..8050b4056f6 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java @@ -26,9 +26,14 @@ import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothProfile; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.database.ContentObserver; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.provider.Settings; import android.util.Log; import androidx.annotation.NonNull; @@ -87,6 +92,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @Nullable private final LocalBluetoothProfileManager mProfileManager; @Nullable private final LocalBluetoothLeBroadcast mBroadcast; @Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant; + @Nullable private final ContentResolver mContentResolver; private final Executor mExecutor; private final MetricsFeatureProvider mMetricsFeatureProvider; @Nullable private PreferenceGroup mPreferenceGroup; @@ -187,6 +193,17 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @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) { super(context, KEY); mBtManager = Utils.getLocalBtManager(mContext); @@ -198,6 +215,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro mProfileManager == null ? null : mProfileManager.getLeAudioBroadcastAssistantProfile(); + mContentResolver = context.getContentResolver(); mExecutor = Executors.newSingleThreadExecutor(); mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @@ -217,6 +235,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro if (mEventManager == null || mAssistant == null || mDialogHandler == null + || mContentResolver == null || mBluetoothDeviceUpdater == null) { Log.d(TAG, "Skip onStart(), profile is not ready."); return; @@ -225,6 +244,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro mEventManager.registerCallback(this); mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback); mDialogHandler.registerCallbacks(mExecutor); + mContentResolver.registerContentObserver( + Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), + false, + mSettingsObserver); mBluetoothDeviceUpdater.registerCallback(); mBluetoothDeviceUpdater.refreshPreference(); mIsAudioModeOngoingCall.set(isAudioModeOngoingCall(mContext)); @@ -245,6 +268,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro if (mEventManager == null || mAssistant == null || mDialogHandler == null + || mContentResolver == null || mBluetoothDeviceUpdater == null) { Log.d(TAG, "Skip onStop(), profile is not ready."); return; @@ -253,6 +277,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro mEventManager.unregisterCallback(this); mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback); mDialogHandler.unregisterCallbacks(); + mContentResolver.unregisterContentObserver(mSettingsObserver); mBluetoothDeviceUpdater.unregisterCallback(); }); } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java index 29f427449e7..a2484127b90 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java @@ -45,6 +45,7 @@ import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; 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.BluetoothCallback; import com.android.settingslib.bluetooth.BluetoothEventManager; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; import com.android.settingslib.bluetooth.HeadsetProfile; @@ -144,6 +146,7 @@ public class AudioSharingDevicePreferenceControllerTest { @Mock private LeAudioProfile mLeAudioProfile; @Mock private A2dpProfile mA2dpProfile; @Mock private HeadsetProfile mHeadsetProfile; + @Mock private ContentResolver mContentResolver; private Context mContext; private AudioSharingDevicePreferenceController mController; @@ -156,7 +159,7 @@ public class AudioSharingDevicePreferenceControllerTest { @Before public void setUp() { - mContext = ApplicationProvider.getApplicationContext(); + mContext = spy(ApplicationProvider.getApplicationContext()); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); mShadowBluetoothAdapter.setEnabled(true); mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( @@ -185,6 +188,7 @@ public class AudioSharingDevicePreferenceControllerTest { when(mA2dpProfile.getProfileId()).thenReturn(BluetoothProfile.A2DP); when(mLeAudioProfile.getProfileId()).thenReturn(BluetoothProfile.LE_AUDIO); when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true); + when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mScreen.getContext()).thenReturn(mContext); mPreferenceGroup = spy(new PreferenceCategory(mContext)); doReturn(mPreferenceManager).when(mPreferenceGroup).getPreferenceManager(); @@ -211,6 +215,12 @@ public class AudioSharingDevicePreferenceControllerTest { verify(mAssistant, never()) .registerServiceCallBack( 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()).refreshPreference(); } @@ -224,6 +234,12 @@ public class AudioSharingDevicePreferenceControllerTest { verify(mAssistant) .registerServiceCallBack( any(Executor.class), any(BluetoothLeBroadcastAssistant.Callback.class)); + verify(mContentResolver) + .registerContentObserver( + Settings.Secure.getUriFor( + BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), + false, + mController.mSettingsObserver); verify(mBluetoothDeviceUpdater).registerCallback(); verify(mBluetoothDeviceUpdater).refreshPreference(); } @@ -236,6 +252,7 @@ public class AudioSharingDevicePreferenceControllerTest { verify(mDialogHandler, never()).unregisterCallbacks(); verify(mAssistant, never()) .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); + verify(mContentResolver, never()).unregisterContentObserver(mController.mSettingsObserver); verify(mBluetoothDeviceUpdater, never()).unregisterCallback(); } @@ -247,6 +264,7 @@ public class AudioSharingDevicePreferenceControllerTest { verify(mDialogHandler).unregisterCallbacks(); verify(mAssistant) .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); + verify(mContentResolver).unregisterContentObserver(mController.mSettingsObserver); verify(mBluetoothDeviceUpdater).unregisterCallback(); } @@ -485,6 +503,12 @@ public class AudioSharingDevicePreferenceControllerTest { verifyNoInteractions(mDialogHandler); } + @Test + public void onFallbackDeviceChanged_updateSummary() { + mController.mSettingsObserver.onChange(true); + verify(mBluetoothDeviceUpdater).refreshPreference(); + } + @Test @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) public void handleDeviceClickFromIntent_noDevice_doNothing() {