1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.connecteddevice.audiosharing; 18 19 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 20 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyInt; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 import static org.robolectric.Shadows.shadowOf; 32 33 import android.app.settings.SettingsEnums; 34 import android.bluetooth.BluetoothAdapter; 35 import android.bluetooth.BluetoothCsipSetCoordinator; 36 import android.bluetooth.BluetoothDevice; 37 import android.bluetooth.BluetoothLeBroadcastAssistant; 38 import android.bluetooth.BluetoothLeBroadcastMetadata; 39 import android.bluetooth.BluetoothLeBroadcastReceiveState; 40 import android.bluetooth.BluetoothProfile; 41 import android.bluetooth.BluetoothStatusCodes; 42 import android.content.ContentResolver; 43 import android.content.Context; 44 import android.database.ContentObserver; 45 import android.os.Looper; 46 import android.platform.test.annotations.DisableFlags; 47 import android.platform.test.annotations.EnableFlags; 48 import android.platform.test.flag.junit.SetFlagsRule; 49 import android.provider.Settings; 50 import android.view.View; 51 import android.widget.CheckedTextView; 52 53 import androidx.appcompat.app.AlertDialog; 54 import androidx.fragment.app.Fragment; 55 import androidx.fragment.app.FragmentActivity; 56 import androidx.lifecycle.LifecycleOwner; 57 import androidx.preference.Preference; 58 import androidx.preference.PreferenceScreen; 59 import androidx.test.core.app.ApplicationProvider; 60 61 import com.android.settings.R; 62 import com.android.settings.bluetooth.Utils; 63 import com.android.settings.testutils.FakeFeatureFactory; 64 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; 65 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; 66 import com.android.settings.testutils.shadow.ShadowBluetoothUtils; 67 import com.android.settings.testutils.shadow.ShadowThreadUtils; 68 import com.android.settingslib.bluetooth.BluetoothEventManager; 69 import com.android.settingslib.bluetooth.BluetoothUtils; 70 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 71 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; 72 import com.android.settingslib.bluetooth.LeAudioProfile; 73 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast; 74 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; 75 import com.android.settingslib.bluetooth.LocalBluetoothManager; 76 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; 77 import com.android.settingslib.bluetooth.VolumeControlProfile; 78 import com.android.settingslib.core.lifecycle.Lifecycle; 79 import com.android.settingslib.flags.Flags; 80 81 import com.google.common.collect.ImmutableList; 82 import com.google.common.collect.ImmutableSet; 83 import com.google.common.collect.Iterables; 84 85 import org.junit.After; 86 import org.junit.Before; 87 import org.junit.Rule; 88 import org.junit.Test; 89 import org.junit.runner.RunWith; 90 import org.mockito.Mock; 91 import org.mockito.Spy; 92 import org.mockito.junit.MockitoJUnit; 93 import org.mockito.junit.MockitoRule; 94 import org.robolectric.RobolectricTestRunner; 95 import org.robolectric.Shadows; 96 import org.robolectric.annotation.Config; 97 import org.robolectric.shadow.api.Shadow; 98 import org.robolectric.shadows.ShadowListView; 99 import org.robolectric.shadows.androidx.fragment.FragmentController; 100 101 import java.util.ArrayList; 102 import java.util.List; 103 104 @RunWith(RobolectricTestRunner.class) 105 @Config( 106 shadows = { 107 ShadowBluetoothAdapter.class, 108 ShadowBluetoothUtils.class, 109 ShadowThreadUtils.class, 110 ShadowAlertDialogCompat.class, 111 }) 112 public class AudioSharingCallAudioPreferenceControllerTest { 113 private static final String PREF_KEY = "calls_and_alarms"; 114 private static final String TEST_DEVICE_NAME1 = "test1"; 115 private static final String TEST_DEVICE_NAME2 = "test2"; 116 private static final int TEST_DEVICE_GROUP_ID1 = 1; 117 private static final int TEST_DEVICE_GROUP_ID2 = 2; 118 119 @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); 120 @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 121 122 @Spy Context mContext = ApplicationProvider.getApplicationContext(); 123 @Mock private PreferenceScreen mScreen; 124 @Mock private LocalBluetoothManager mLocalBtManager; 125 @Mock private BluetoothEventManager mBtEventManager; 126 @Mock private LocalBluetoothProfileManager mBtProfileManager; 127 @Mock private CachedBluetoothDeviceManager mCacheManager; 128 @Mock private LeAudioProfile mLeaProfile; 129 @Mock private LocalBluetoothLeBroadcast mBroadcast; 130 @Mock private LocalBluetoothLeBroadcastAssistant mAssistant; 131 @Mock private VolumeControlProfile mVolumeControl; 132 @Mock private BluetoothDevice mDevice1; 133 @Mock private BluetoothDevice mDevice2; 134 @Mock private BluetoothDevice mDevice3; 135 @Mock private CachedBluetoothDevice mCachedDevice1; 136 @Mock private CachedBluetoothDevice mCachedDevice2; 137 @Mock private CachedBluetoothDevice mCachedDevice3; 138 @Mock private BluetoothLeBroadcastReceiveState mState; 139 @Mock private BluetoothLeBroadcastMetadata mSource; 140 @Mock private ContentResolver mContentResolver; 141 private AudioSharingCallAudioPreferenceController mController; 142 @Spy private ContentObserver mContentObserver; 143 private ShadowBluetoothAdapter mShadowBluetoothAdapter; 144 private FakeFeatureFactory mFeatureFactory; 145 private Lifecycle mLifecycle; 146 private LifecycleOwner mLifecycleOwner; 147 private Preference mPreference; 148 private Fragment mParentFragment; 149 150 @Before setUp()151 public void setUp() { 152 ShadowAlertDialogCompat.reset(); 153 mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); 154 mShadowBluetoothAdapter.setEnabled(true); 155 mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( 156 BluetoothStatusCodes.FEATURE_SUPPORTED); 157 mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( 158 BluetoothStatusCodes.FEATURE_SUPPORTED); 159 mLifecycleOwner = () -> mLifecycle; 160 mLifecycle = new Lifecycle(mLifecycleOwner); 161 mParentFragment = new Fragment(); 162 FragmentController.setupFragment( 163 mParentFragment, 164 FragmentActivity.class, 165 0 /* containerViewId */, 166 null /* bundle */); 167 ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager; 168 LocalBluetoothManager btManager = Utils.getLocalBtManager(mContext); 169 mFeatureFactory = FakeFeatureFactory.setupForTest(); 170 when(btManager.getEventManager()).thenReturn(mBtEventManager); 171 when(btManager.getProfileManager()).thenReturn(mBtProfileManager); 172 when(btManager.getCachedDeviceManager()).thenReturn(mCacheManager); 173 when(mBtProfileManager.getLeAudioProfile()).thenReturn(mLeaProfile); 174 when(mBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast); 175 when(mBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant); 176 when(mBtProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl); 177 when(mBroadcast.isProfileReady()).thenReturn(true); 178 when(mAssistant.isProfileReady()).thenReturn(true); 179 when(mVolumeControl.isProfileReady()).thenReturn(true); 180 List<Long> bisSyncState = new ArrayList<>(); 181 bisSyncState.add(1L); 182 when(mState.getBisSyncState()).thenReturn(bisSyncState); 183 when(mContext.getContentResolver()).thenReturn(mContentResolver); 184 when(mCachedDevice1.getDevice()).thenReturn(mDevice1); 185 when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); 186 when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); 187 when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false); 188 when(mCachedDevice1.getMemberDevice()).thenReturn(ImmutableSet.of(mCachedDevice2)); 189 when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); 190 when(mCachedDevice2.getDevice()).thenReturn(mDevice2); 191 when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); 192 when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME1); 193 when(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false); 194 when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); 195 when(mCachedDevice3.getDevice()).thenReturn(mDevice3); 196 when(mCachedDevice3.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); 197 when(mCachedDevice3.getName()).thenReturn(TEST_DEVICE_NAME2); 198 when(mCachedDevice3.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false); 199 when(mCacheManager.findDevice(mDevice3)).thenReturn(mCachedDevice3); 200 mController = new AudioSharingCallAudioPreferenceController(mContext); 201 mController.init(null); 202 mContentObserver = mController.getSettingsObserver(); 203 mPreference = new Preference(mContext); 204 when(mScreen.findPreference(PREF_KEY)).thenReturn(mPreference); 205 } 206 207 @After tearDown()208 public void tearDown() { 209 ShadowAlertDialogCompat.reset(); 210 ShadowThreadUtils.reset(); 211 ShadowBluetoothUtils.reset(); 212 } 213 214 @Test 215 @DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) onStart_flagOff_doNothing()216 public void onStart_flagOff_doNothing() { 217 mController.onStart(mLifecycleOwner); 218 verify(mBtEventManager, never()).registerCallback(mController); 219 verify(mContentResolver, never()) 220 .registerContentObserver( 221 Settings.Secure.getUriFor( 222 BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), 223 false, 224 mContentObserver); 225 verify(mAssistant, never()) 226 .registerServiceCallBack(any(), any(BluetoothLeBroadcastAssistant.Callback.class)); 227 } 228 229 @Test 230 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) onStart_flagOn_registerCallback()231 public void onStart_flagOn_registerCallback() { 232 mController.onStart(mLifecycleOwner); 233 verify(mBtEventManager).registerCallback(mController); 234 verify(mContentResolver) 235 .registerContentObserver( 236 Settings.Secure.getUriFor( 237 BluetoothUtils.getPrimaryGroupIdUriForBroadcast()), 238 false, 239 mContentObserver); 240 verify(mAssistant) 241 .registerServiceCallBack(any(), any(BluetoothLeBroadcastAssistant.Callback.class)); 242 } 243 244 @Test 245 @DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) onStop_flagOff_doNothing()246 public void onStop_flagOff_doNothing() { 247 mController.setCallbacksRegistered(true); 248 mController.onStop(mLifecycleOwner); 249 verify(mBtEventManager, never()).unregisterCallback(mController); 250 verify(mContentResolver, never()).unregisterContentObserver(mContentObserver); 251 verify(mAssistant, never()) 252 .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); 253 } 254 255 @Test 256 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) onStop_flagOn_notRegistered_doNothing()257 public void onStop_flagOn_notRegistered_doNothing() { 258 mController.setCallbacksRegistered(false); 259 mController.onStop(mLifecycleOwner); 260 verify(mBtEventManager, never()).unregisterCallback(mController); 261 verify(mContentResolver, never()).unregisterContentObserver(mContentObserver); 262 verify(mAssistant, never()) 263 .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); 264 } 265 266 @Test 267 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) onStop_flagOn_registered_unregisterCallback()268 public void onStop_flagOn_registered_unregisterCallback() { 269 mController.setCallbacksRegistered(true); 270 mController.onStop(mLifecycleOwner); 271 verify(mBtEventManager).unregisterCallback(mController); 272 verify(mContentResolver).unregisterContentObserver(mContentObserver); 273 verify(mAssistant) 274 .unregisterServiceCallBack(any(BluetoothLeBroadcastAssistant.Callback.class)); 275 } 276 277 @Test 278 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) getAvailabilityStatus_flagOn()279 public void getAvailabilityStatus_flagOn() { 280 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 281 } 282 283 @Test 284 @DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) getAvailabilityStatus_flagOff()285 public void getAvailabilityStatus_flagOff() { 286 assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); 287 } 288 289 @Test 290 @DisableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) updateVisibility_flagOff_invisible()291 public void updateVisibility_flagOff_invisible() { 292 when(mBroadcast.isEnabled(any())).thenReturn(true); 293 mController.displayPreference(mScreen); 294 mController.updateVisibility(); 295 shadowOf(Looper.getMainLooper()).idle(); 296 assertThat(mPreference.isVisible()).isFalse(); 297 } 298 299 @Test 300 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) updateVisibility_broadcastOffBluetoothOff_invisible()301 public void updateVisibility_broadcastOffBluetoothOff_invisible() { 302 when(mBroadcast.isEnabled(any())).thenReturn(false); 303 mShadowBluetoothAdapter.setEnabled(false); 304 mController.displayPreference(mScreen); 305 mController.updateVisibility(); 306 shadowOf(Looper.getMainLooper()).idle(); 307 assertThat(mPreference.isVisible()).isFalse(); 308 } 309 310 @Test 311 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) updateVisibility_broadcastOnBluetoothOff_invisible()312 public void updateVisibility_broadcastOnBluetoothOff_invisible() { 313 when(mBroadcast.isEnabled(any())).thenReturn(true); 314 mShadowBluetoothAdapter.setEnabled(false); 315 mController.displayPreference(mScreen); 316 mController.updateVisibility(); 317 shadowOf(Looper.getMainLooper()).idle(); 318 assertThat(mPreference.isVisible()).isFalse(); 319 } 320 321 @Test 322 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) updateVisibility_broadcastOffBluetoothOn_invisible()323 public void updateVisibility_broadcastOffBluetoothOn_invisible() { 324 when(mBroadcast.isEnabled(any())).thenReturn(false); 325 mController.displayPreference(mScreen); 326 mController.updateVisibility(); 327 shadowOf(Looper.getMainLooper()).idle(); 328 assertThat(mPreference.isVisible()).isFalse(); 329 } 330 331 @Test 332 @EnableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING) updateVisibility_broadcastOnBluetoothOn_visible()333 public void updateVisibility_broadcastOnBluetoothOn_visible() { 334 when(mBroadcast.isEnabled(any())).thenReturn(true); 335 mController.displayPreference(mScreen); 336 mController.updateVisibility(); 337 shadowOf(Looper.getMainLooper()).idle(); 338 assertThat(mPreference.isVisible()).isTrue(); 339 } 340 341 @Test 342 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) onProfileConnectionStateChanged_adoptApi_noDeviceInSharing_updateSummary()343 public void onProfileConnectionStateChanged_adoptApi_noDeviceInSharing_updateSummary() { 344 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID1); 345 when(mBroadcast.isEnabled(any())).thenReturn(true); 346 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 347 mController.displayPreference(mScreen); 348 shadowOf(Looper.getMainLooper()).idle(); 349 mPreference.setSummary("test"); 350 351 mController.onProfileConnectionStateChanged( 352 mCachedDevice1, 353 BluetoothAdapter.STATE_DISCONNECTED, 354 BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); 355 shadowOf(Looper.getMainLooper()).idle(); 356 assertThat(mPreference.getSummary().toString()).isEmpty(); 357 } 358 359 @Test 360 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) onFallbackDeviceChanged_adoptApi_updateSummary()361 public void onFallbackDeviceChanged_adoptApi_updateSummary() { 362 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID1); 363 when(mBroadcast.isEnabled(any())).thenReturn(true); 364 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 365 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 366 mController.displayPreference(mScreen); 367 shadowOf(Looper.getMainLooper()).idle(); 368 mPreference.setSummary("test"); 369 370 mContentObserver.onChange(true); 371 shadowOf(Looper.getMainLooper()).idle(); 372 assertThat(mPreference.getSummary().toString()) 373 .isEqualTo( 374 mContext.getString( 375 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 376 } 377 378 @Test 379 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) onActiveDeviceChanged_adoptApi_updateSummary()380 public void onActiveDeviceChanged_adoptApi_updateSummary() { 381 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn( 382 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 383 when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); 384 when(mBroadcast.isEnabled(any())).thenReturn(true); 385 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 386 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 387 mController.displayPreference(mScreen); 388 shadowOf(Looper.getMainLooper()).idle(); 389 mPreference.setSummary("test"); 390 391 mController.onActiveDeviceChanged(mCachedDevice1, BluetoothProfile.LE_AUDIO); 392 shadowOf(Looper.getMainLooper()).idle(); 393 assertThat(mPreference.getSummary().toString()) 394 .isEqualTo( 395 mContext.getString( 396 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 397 } 398 399 @Test 400 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_adoptApi_fallbackDeviceInSharing_showCorrectSummary()401 public void displayPreference_adoptApi_fallbackDeviceInSharing_showCorrectSummary() { 402 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID1); 403 when(mCachedDevice3.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); 404 when(mBroadcast.isEnabled(any())).thenReturn(true); 405 when(mAssistant.getAllConnectedDevices()) 406 .thenReturn(ImmutableList.of(mDevice1, mDevice2, mDevice3)); 407 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 408 mController.displayPreference(mScreen); 409 shadowOf(Looper.getMainLooper()).idle(); 410 assertThat(mPreference.getSummary().toString()) 411 .isEqualTo( 412 mContext.getString( 413 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 414 } 415 416 @Test 417 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_adoptApi_activeDeviceInSharing_showCorrectSummary()418 public void displayPreference_adoptApi_activeDeviceInSharing_showCorrectSummary() { 419 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID2); 420 when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); 421 when(mBroadcast.isEnabled(any())).thenReturn(true); 422 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); 423 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 424 mController.displayPreference(mScreen); 425 shadowOf(Looper.getMainLooper()).idle(); 426 assertThat(mPreference.getSummary().toString()) 427 .isEqualTo(mContext.getString( 428 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 429 } 430 431 @Test 432 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_adoptApi_noFallbackDeviceOrActiveInSharing_showEmptySummary()433 public void displayPreference_adoptApi_noFallbackDeviceOrActiveInSharing_showEmptySummary() { 434 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID2); 435 when(mBroadcast.isEnabled(any())).thenReturn(true); 436 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); 437 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 438 mController.displayPreference(mScreen); 439 shadowOf(Looper.getMainLooper()).idle(); 440 assertThat(mPreference.getSummary().toString()).isEmpty(); 441 } 442 443 @Test 444 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_adoptApi_noFallbackOrActiveDevice_showEmptySummary()445 public void displayPreference_adoptApi_noFallbackOrActiveDevice_showEmptySummary() { 446 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn( 447 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 448 when(mBroadcast.isEnabled(any())).thenReturn(true); 449 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 450 mController.displayPreference(mScreen); 451 shadowOf(Looper.getMainLooper()).idle(); 452 assertThat(mPreference.getSummary().toString()).isEmpty(); 453 } 454 455 @Test 456 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_adoptApi_clickToShowCorrectDialog()457 public void displayPreference_adoptApi_clickToShowCorrectDialog() { 458 AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); 459 if (latestAlertDialog != null) { 460 latestAlertDialog.dismiss(); 461 ShadowAlertDialogCompat.reset(); 462 } 463 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID1); 464 mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( 465 List.of(mDevice1, mDevice2, mDevice3)); 466 when(mBroadcast.isEnabled(any())).thenReturn(true); 467 when(mAssistant.getAllConnectedDevices()).thenReturn( 468 ImmutableList.of(mDevice1, mDevice2, mDevice3)); 469 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 470 mController.init(mParentFragment); 471 mController.displayPreference(mScreen); 472 shadowOf(Looper.getMainLooper()).idle(); 473 mPreference.performClick(); 474 shadowOf(Looper.getMainLooper()).idle(); 475 AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); 476 assertThat(dialog.isShowing()).isTrue(); 477 assertThat(dialog.getListView().getCount()).isEqualTo(2); 478 ArrayList<View> outViews = new ArrayList<>(); 479 dialog.getListView() 480 .findViewsWithText(outViews, TEST_DEVICE_NAME1, View.FIND_VIEWS_WITH_TEXT); 481 assertThat(outViews.size()).isEqualTo(1); 482 View view = Iterables.getOnlyElement(outViews); 483 assertThat(view instanceof CheckedTextView).isTrue(); 484 assertThat(((CheckedTextView) view).isChecked()).isTrue(); 485 verify(mFeatureFactory.metricsFeatureProvider) 486 .visible( 487 /* context= */ eq(null), 488 /* source= */ anyInt(), 489 eq(SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO), 490 /* latency= */ anyInt()); 491 } 492 493 @Test 494 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) testBluetoothLeBroadcastAssistantCallbacks_adoptApi_updateSummary()495 public void testBluetoothLeBroadcastAssistantCallbacks_adoptApi_updateSummary() { 496 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn( 497 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 498 when(mBroadcast.isEnabled(any())).thenReturn(true); 499 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 500 mController.displayPreference(mScreen); 501 shadowOf(Looper.getMainLooper()).idle(); 502 assertThat(mPreference.getSummary().toString()).isEmpty(); 503 504 // onSourceAdded will update summary 505 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID1); 506 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 507 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 508 mController.mBroadcastAssistantCallback.onSourceAdded(mDevice1, /* sourceId= */ 509 1, /* reason= */ 1); 510 shadowOf(Looper.getMainLooper()).idle(); 511 assertThat(mPreference.getSummary().toString()) 512 .isEqualTo( 513 mContext.getString( 514 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 515 } 516 517 @Test 518 @EnableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) testBluetoothLeBroadcastAssistantCallbacks_adoptApi_doNothing()519 public void testBluetoothLeBroadcastAssistantCallbacks_adoptApi_doNothing() { 520 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn( 521 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 522 when(mBroadcast.isEnabled(any())).thenReturn(true); 523 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 524 mController.displayPreference(mScreen); 525 shadowOf(Looper.getMainLooper()).idle(); 526 assertThat(mPreference.getSummary().toString()).isEmpty(); 527 528 when(mLeaProfile.getBroadcastToUnicastFallbackGroup()).thenReturn(TEST_DEVICE_GROUP_ID1); 529 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 530 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 531 mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1); 532 mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); 533 mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); 534 mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); 535 mController.mBroadcastAssistantCallback.onSourceAddFailed( 536 mDevice1, mSource, /* reason= */ 1); 537 mController.mBroadcastAssistantCallback.onSourceRemoved( 538 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 539 mController.mBroadcastAssistantCallback.onSourceRemoveFailed( 540 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 541 mController.mBroadcastAssistantCallback.onSourceModified( 542 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 543 mController.mBroadcastAssistantCallback.onSourceModifyFailed( 544 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 545 mController.mBroadcastAssistantCallback.onSourceFound(mSource); 546 mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1); 547 shadowOf(Looper.getMainLooper()).idle(); 548 mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1, 549 mState); 550 551 // Above callbacks won't update summary. 552 assertThat(mPreference.getSummary().toString()).isEmpty(); 553 } 554 555 @Test 556 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) onProfileConnectionStateChanged_noDeviceInSharing_updateSummary()557 public void onProfileConnectionStateChanged_noDeviceInSharing_updateSummary() { 558 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 559 TEST_DEVICE_GROUP_ID1); 560 when(mBroadcast.isEnabled(any())).thenReturn(true); 561 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 562 mController.displayPreference(mScreen); 563 shadowOf(Looper.getMainLooper()).idle(); 564 mPreference.setSummary("test"); 565 566 mController.onProfileConnectionStateChanged( 567 mCachedDevice1, 568 BluetoothAdapter.STATE_DISCONNECTED, 569 BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT); 570 shadowOf(Looper.getMainLooper()).idle(); 571 assertThat(mPreference.getSummary().toString()).isEmpty(); 572 } 573 574 @Test 575 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) onFallbackDeviceChanged_updateSummary()576 public void onFallbackDeviceChanged_updateSummary() { 577 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 578 TEST_DEVICE_GROUP_ID1); 579 when(mBroadcast.isEnabled(any())).thenReturn(true); 580 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 581 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 582 mController.displayPreference(mScreen); 583 shadowOf(Looper.getMainLooper()).idle(); 584 mPreference.setSummary("test"); 585 586 mContentObserver.onChange(true); 587 shadowOf(Looper.getMainLooper()).idle(); 588 assertThat(mPreference.getSummary().toString()) 589 .isEqualTo( 590 mContext.getString( 591 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 592 } 593 594 @Test 595 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) onActiveDeviceChanged_updateSummary()596 public void onActiveDeviceChanged_updateSummary() { 597 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 598 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 599 when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); 600 when(mBroadcast.isEnabled(any())).thenReturn(true); 601 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 602 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 603 mController.displayPreference(mScreen); 604 shadowOf(Looper.getMainLooper()).idle(); 605 mPreference.setSummary("test"); 606 607 mController.onActiveDeviceChanged(mCachedDevice1, BluetoothProfile.LE_AUDIO); 608 shadowOf(Looper.getMainLooper()).idle(); 609 assertThat(mPreference.getSummary().toString()) 610 .isEqualTo( 611 mContext.getString( 612 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 613 } 614 615 @Test 616 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_fallbackDeviceInSharing_showCorrectSummary()617 public void displayPreference_fallbackDeviceInSharing_showCorrectSummary() { 618 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 619 TEST_DEVICE_GROUP_ID1); 620 when(mCachedDevice3.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); 621 when(mBroadcast.isEnabled(any())).thenReturn(true); 622 when(mAssistant.getAllConnectedDevices()) 623 .thenReturn(ImmutableList.of(mDevice1, mDevice2, mDevice3)); 624 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 625 mController.displayPreference(mScreen); 626 shadowOf(Looper.getMainLooper()).idle(); 627 assertThat(mPreference.getSummary().toString()) 628 .isEqualTo( 629 mContext.getString( 630 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 631 } 632 633 @Test 634 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_activeDeviceInSharing_showCorrectSummary()635 public void displayPreference_activeDeviceInSharing_showCorrectSummary() { 636 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 637 TEST_DEVICE_GROUP_ID2); 638 when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); 639 when(mBroadcast.isEnabled(any())).thenReturn(true); 640 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); 641 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 642 mController.displayPreference(mScreen); 643 shadowOf(Looper.getMainLooper()).idle(); 644 assertThat(mPreference.getSummary().toString()) 645 .isEqualTo(mContext.getString( 646 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 647 } 648 649 @Test 650 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_noFallbackDeviceOrActiveInSharing_showEmptySummary()651 public void displayPreference_noFallbackDeviceOrActiveInSharing_showEmptySummary() { 652 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 653 TEST_DEVICE_GROUP_ID2); 654 when(mBroadcast.isEnabled(any())).thenReturn(true); 655 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); 656 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 657 mController.displayPreference(mScreen); 658 shadowOf(Looper.getMainLooper()).idle(); 659 assertThat(mPreference.getSummary().toString()).isEmpty(); 660 } 661 662 @Test 663 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_noFallbackOrActiveDevice_showEmptySummary()664 public void displayPreference_noFallbackOrActiveDevice_showEmptySummary() { 665 Settings.Secure.putInt( 666 mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 667 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 668 when(mBroadcast.isEnabled(any())).thenReturn(true); 669 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 670 mController.displayPreference(mScreen); 671 shadowOf(Looper.getMainLooper()).idle(); 672 assertThat(mPreference.getSummary().toString()).isEmpty(); 673 } 674 675 @Test 676 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) displayPreference_clickToShowCorrectDialog()677 public void displayPreference_clickToShowCorrectDialog() { 678 AlertDialog latestAlertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); 679 if (latestAlertDialog != null) { 680 latestAlertDialog.dismiss(); 681 ShadowAlertDialogCompat.reset(); 682 } 683 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 684 TEST_DEVICE_GROUP_ID1); 685 mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( 686 List.of(mDevice1, mDevice2, mDevice3)); 687 when(mBroadcast.isEnabled(any())).thenReturn(true); 688 when(mAssistant.getAllConnectedDevices()).thenReturn( 689 ImmutableList.of(mDevice1, mDevice2, mDevice3)); 690 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 691 mController.init(mParentFragment); 692 mController.displayPreference(mScreen); 693 shadowOf(Looper.getMainLooper()).idle(); 694 mPreference.performClick(); 695 shadowOf(Looper.getMainLooper()).idle(); 696 AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); 697 assertThat(dialog.isShowing()).isTrue(); 698 assertThat(dialog.getListView().getCount()).isEqualTo(2); 699 ShadowListView listView = Shadows.shadowOf(dialog.getListView()); 700 View view1 = listView.findItemContainingText(TEST_DEVICE_NAME1); 701 assertThat(view1).isNotNull(); 702 assertThat(view1 instanceof CheckedTextView).isTrue(); 703 assertThat(((CheckedTextView) view1).isChecked()).isTrue(); 704 View view2 = listView.findItemContainingText(TEST_DEVICE_NAME2); 705 assertThat(view2).isNotNull(); 706 assertThat(view2 instanceof CheckedTextView).isTrue(); 707 assertThat(((CheckedTextView) view2).isChecked()).isFalse(); 708 709 verify(mFeatureFactory.metricsFeatureProvider) 710 .visible( 711 /* context= */ eq(null), 712 /* source= */ anyInt(), 713 eq(SettingsEnums.DIALOG_AUDIO_SHARING_CALL_AUDIO), 714 /* latency= */ anyInt()); 715 716 LeAudioProfile leAudioProfile = mock(LeAudioProfile.class); 717 when(mBtProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile); 718 719 // Perform click to switch call audio device by set active 720 mSetFlagsRule.disableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); 721 int index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME2); 722 listView.performItemClick(index); 723 shadowOf(Looper.getMainLooper()).idle(); 724 assertThat(((CheckedTextView) view1).isChecked()).isFalse(); 725 assertThat(((CheckedTextView) view2).isChecked()).isTrue(); 726 verify(mCachedDevice3).setActive(); 727 verify(leAudioProfile, never()).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID2); 728 729 // Perform click to switch call audio device with API 730 mSetFlagsRule.enableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API); 731 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 732 TEST_DEVICE_GROUP_ID2); 733 index = listView.findIndexOfItemContainingText(TEST_DEVICE_NAME1); 734 listView.performItemClick(index); 735 shadowOf(Looper.getMainLooper()).idle(); 736 assertThat(((CheckedTextView) view1).isChecked()).isTrue(); 737 assertThat(((CheckedTextView) view2).isChecked()).isFalse(); 738 verify(mCachedDevice1, never()).setActive(); 739 verify(leAudioProfile).setBroadcastToUnicastFallbackGroup(TEST_DEVICE_GROUP_ID1); 740 } 741 742 @Test logCallAudioDeviceChange_changeCallAudioToEarlierConnectedDevice()743 public void logCallAudioDeviceChange_changeCallAudioToEarlierConnectedDevice() { 744 mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( 745 List.of(mDevice1, mDevice2, mDevice3)); 746 mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID1, mCachedDevice3); 747 verify(mFeatureFactory.metricsFeatureProvider) 748 .action( 749 mContext, 750 SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_CALL_AUDIO, 751 AudioSharingCallAudioPreferenceController.ChangeCallAudioType 752 .CONNECTED_EARLIER 753 .ordinal()); 754 } 755 756 @Test logCallAudioDeviceChange_changeCallAudioToLaterConnectedDevice()757 public void logCallAudioDeviceChange_changeCallAudioToLaterConnectedDevice() { 758 mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( 759 List.of(mDevice1, mDevice2, mDevice3)); 760 mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID2, mCachedDevice1); 761 verify(mFeatureFactory.metricsFeatureProvider) 762 .action( 763 mContext, 764 SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_CALL_AUDIO, 765 AudioSharingCallAudioPreferenceController.ChangeCallAudioType 766 .CONNECTED_LATER 767 .ordinal()); 768 } 769 770 @Test logCallAudioDeviceChange_deviceNotFoundInRecentList_unknownChangeType()771 public void logCallAudioDeviceChange_deviceNotFoundInRecentList_unknownChangeType() { 772 mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1, mDevice2)); 773 mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID1, mCachedDevice3); 774 verify(mFeatureFactory.metricsFeatureProvider) 775 .action( 776 mContext, 777 SettingsEnums.ACTION_AUDIO_SHARING_CHANGE_CALL_AUDIO, 778 AudioSharingCallAudioPreferenceController.ChangeCallAudioType.UNKNOWN 779 .ordinal()); 780 } 781 782 @Test 783 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) testBluetoothLeBroadcastAssistantCallbacks_updateSummary()784 public void testBluetoothLeBroadcastAssistantCallbacks_updateSummary() { 785 Settings.Secure.putInt( 786 mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 787 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 788 when(mBroadcast.isEnabled(any())).thenReturn(true); 789 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 790 mController.displayPreference(mScreen); 791 shadowOf(Looper.getMainLooper()).idle(); 792 assertThat(mPreference.getSummary().toString()).isEmpty(); 793 794 // onSourceAdded will update summary 795 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 796 TEST_DEVICE_GROUP_ID1); 797 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 798 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 799 mController.mBroadcastAssistantCallback.onSourceAdded(mDevice1, /* sourceId= */ 800 1, /* reason= */ 1); 801 shadowOf(Looper.getMainLooper()).idle(); 802 assertThat(mPreference.getSummary().toString()) 803 .isEqualTo( 804 mContext.getString( 805 R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); 806 } 807 808 @Test 809 @DisableFlags(Flags.FLAG_ADOPT_PRIMARY_GROUP_MANAGEMENT_API_V2) testBluetoothLeBroadcastAssistantCallbacks_doNothing()810 public void testBluetoothLeBroadcastAssistantCallbacks_doNothing() { 811 Settings.Secure.putInt( 812 mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 813 BluetoothCsipSetCoordinator.GROUP_ID_INVALID); 814 when(mBroadcast.isEnabled(any())).thenReturn(true); 815 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); 816 mController.displayPreference(mScreen); 817 shadowOf(Looper.getMainLooper()).idle(); 818 assertThat(mPreference.getSummary().toString()).isEmpty(); 819 820 Settings.Secure.putInt(mContentResolver, BluetoothUtils.getPrimaryGroupIdUriForBroadcast(), 821 TEST_DEVICE_GROUP_ID1); 822 when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); 823 when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); 824 mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1); 825 mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); 826 mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); 827 mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); 828 mController.mBroadcastAssistantCallback.onSourceAddFailed( 829 mDevice1, mSource, /* reason= */ 1); 830 mController.mBroadcastAssistantCallback.onSourceRemoved( 831 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 832 mController.mBroadcastAssistantCallback.onSourceRemoveFailed( 833 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 834 mController.mBroadcastAssistantCallback.onSourceModified( 835 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 836 mController.mBroadcastAssistantCallback.onSourceModifyFailed( 837 mDevice1, /* sourceId= */ 1, /* reason= */ 1); 838 mController.mBroadcastAssistantCallback.onSourceFound(mSource); 839 mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1); 840 shadowOf(Looper.getMainLooper()).idle(); 841 mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1, 842 mState); 843 844 // Above callbacks won't update summary. 845 assertThat(mPreference.getSummary().toString()).isEmpty(); 846 } 847 } 848