diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java index 168fce51dc4..468ac3d5652 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java @@ -31,6 +31,7 @@ import android.os.Handler; import android.os.Looper; import android.provider.Settings; import android.util.Log; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -195,40 +196,33 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP } updateDeviceItemsInSharingSession(); if (!mDeviceItemsInSharingSession.isEmpty()) { - int checkedItemIndex = getActiveItemIndex(mDeviceItemsInSharingSession); + Pair pair = getActiveItemWithIndex(); AudioSharingCallAudioDialogFragment.show( mFragment, mDeviceItemsInSharingSession, - checkedItemIndex, + pair == null ? -1 : pair.first, (AudioSharingDeviceItem item) -> { int currentGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast( mContext.getContentResolver()); - if (item.getGroupId() == currentGroupId) { - Log.d( - TAG, - "Skip set fallback active device: unchanged"); + int clickedGroupId = item.getGroupId(); + if (clickedGroupId == currentGroupId) { + Log.d(TAG, "Skip set call audio device: unchanged"); return; } List devices = mGroupedConnectedDevices.getOrDefault( - item.getGroupId(), ImmutableList.of()); + clickedGroupId, ImmutableList.of()); CachedBluetoothDevice lead = AudioSharingUtils.getLeadDevice( mCacheManager, devices); if (lead != null) { - Log.d( - TAG, - "Set fallback active device: " - + lead.getDevice() - .getAnonymizedAddress()); + String addr = lead.getDevice().getAnonymizedAddress(); + Log.d(TAG, "Set call audio device: " + addr); lead.setActive(); logCallAudioDeviceChange(currentGroupId, lead); } else { - Log.d( - TAG, - "Fail to set fallback active device: no" - + " lead device"); + Log.d(TAG, "Skip set call audio device: no lead"); } }); } @@ -263,6 +257,18 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP } } + @Override + public void onActiveDeviceChanged(@Nullable CachedBluetoothDevice activeDevice, + int bluetoothProfile) { + if (activeDevice != null && bluetoothProfile == BluetoothProfile.LE_AUDIO + && BluetoothUtils.isBroadcasting(mBtManager)) { + Log.d(TAG, "onActiveDeviceChanged: update summary, device = " + + activeDevice.getDevice().getAnonymizedAddress() + + ", profile = " + bluetoothProfile); + updateSummary(); + } + } + /** * Initialize the controller. * @@ -348,30 +354,22 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP */ private void updateSummary() { updateDeviceItemsInSharingSession(); - int fallbackActiveGroupId = - BluetoothUtils.getPrimaryGroupIdForBroadcast(mContext.getContentResolver()); - if (fallbackActiveGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { - for (AudioSharingDeviceItem item : mDeviceItemsInSharingSession) { - if (item.getGroupId() == fallbackActiveGroupId) { - Log.d( - TAG, - "updatePreference: set summary to fallback group " - + fallbackActiveGroupId); - AudioSharingUtils.postOnMainThread( - mContext, - () -> { - if (mPreference != null) { - mPreference.setSummary( - mContext.getString( - R.string.audio_sharing_call_audio_description, - item.getName())); - } - }); - return; - } - } + Pair pair = getActiveItemWithIndex(); + if (pair != null) { + Log.d(TAG, "updateSummary, group = " + pair.second.getGroupId()); + AudioSharingUtils.postOnMainThread( + mContext, + () -> { + if (mPreference != null) { + mPreference.setSummary( + mContext.getString( + R.string.audio_sharing_call_audio_description, + pair.second.getName())); + } + }); + return; } - Log.d(TAG, "updatePreference: set empty summary"); + Log.d(TAG, "updateSummary: set empty"); AudioSharingUtils.postOnMainThread( mContext, () -> { @@ -388,16 +386,26 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP mBtManager, mGroupedConnectedDevices, /* filterByInSharing= */ true); } - private int getActiveItemIndex(List deviceItems) { - int checkedItemIndex = -1; + @Nullable + private Pair getActiveItemWithIndex() { + List deviceItems = new ArrayList<>(mDeviceItemsInSharingSession); int fallbackActiveGroupId = BluetoothUtils.getPrimaryGroupIdForBroadcast(mContext.getContentResolver()); - for (AudioSharingDeviceItem item : deviceItems) { - if (item.getGroupId() == fallbackActiveGroupId) { - return deviceItems.indexOf(item); + if (fallbackActiveGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) { + for (AudioSharingDeviceItem item : deviceItems) { + if (item.getGroupId() == fallbackActiveGroupId) { + Log.d(TAG, "getActiveItemWithIndex, fallback group = " + item.getGroupId()); + return new Pair<>(deviceItems.indexOf(item), item); + } } } - return checkedItemIndex; + for (AudioSharingDeviceItem item : deviceItems) { + if (item.isActive()) { + Log.d(TAG, "getActiveItemWithIndex, active LEA group = " + item.getGroupId()); + return new Pair<>(deviceItems.indexOf(item), item); + } + } + return null; } @VisibleForTesting diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItem.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItem.java index 5998e30c5bc..ca62dc39d80 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItem.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItem.java @@ -19,6 +19,8 @@ package com.android.settings.connecteddevice.audiosharing; import android.os.Parcel; import android.os.Parcelable; +import androidx.annotation.NonNull; + public final class AudioSharingDeviceItem implements Parcelable { private final String mName; private final int mGroupId; @@ -72,4 +74,10 @@ public final class AudioSharingDeviceItem implements Parcelable { return new AudioSharingDeviceItem[size]; } }; + + @Override + @NonNull + public String toString() { + return "AudioSharingDeviceItem groupId = " + mGroupId + ", isActive = " + mIsActive; + } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java index 87ae3d5431f..a575d5ab7d7 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java @@ -176,6 +176,22 @@ public class AudioSharingCallAudioPreferenceControllerTest { bisSyncState.add(1L); when(mState.getBisSyncState()).thenReturn(bisSyncState); when(mContext.getContentResolver()).thenReturn(mContentResolver); + when(mCachedDevice1.getDevice()).thenReturn(mDevice1); + when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); + when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); + when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false); + when(mCachedDevice1.getMemberDevice()).thenReturn(ImmutableSet.of(mCachedDevice2)); + when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); + when(mCachedDevice2.getDevice()).thenReturn(mDevice2); + when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); + when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME1); + when(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false); + when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); + when(mCachedDevice3.getDevice()).thenReturn(mDevice3); + when(mCachedDevice3.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); + when(mCachedDevice3.getName()).thenReturn(TEST_DEVICE_NAME2); + when(mCachedDevice3.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false); + when(mCacheManager.findDevice(mDevice3)).thenReturn(mCachedDevice3); mController = new AudioSharingCallAudioPreferenceController(mContext); mController.init(null); mContentObserver = mController.getSettingsObserver(); @@ -323,7 +339,9 @@ public class AudioSharingCallAudioPreferenceControllerTest { when(mBroadcast.isEnabled(any())).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of()); mController.displayPreference(mScreen); + shadowOf(Looper.getMainLooper()).idle(); mPreference.setSummary("test"); + mController.onProfileConnectionStateChanged( mCachedDevice1, BluetoothAdapter.STATE_DISCONNECTED, @@ -335,14 +353,13 @@ public class AudioSharingCallAudioPreferenceControllerTest { @Test public void onFallbackDeviceChanged_updateSummary() { Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); when(mBroadcast.isEnabled(any())).thenReturn(true); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); mController.displayPreference(mScreen); + shadowOf(Looper.getMainLooper()).idle(); + mPreference.setSummary("test"); + mContentObserver.onChange(true); shadowOf(Looper.getMainLooper()).idle(); assertThat(mPreference.getSummary().toString()) @@ -352,20 +369,29 @@ public class AudioSharingCallAudioPreferenceControllerTest { } @Test - public void displayPreference_showCorrectSummary() { + public void onActiveDeviceChanged_updateSummary() { + Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, + BluetoothCsipSetCoordinator.GROUP_ID_INVALID); + when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); + when(mBroadcast.isEnabled(any())).thenReturn(true); + when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); + when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); + mController.displayPreference(mScreen); + shadowOf(Looper.getMainLooper()).idle(); + mPreference.setSummary("test"); + + mController.onActiveDeviceChanged(mCachedDevice1, BluetoothProfile.LE_AUDIO); + shadowOf(Looper.getMainLooper()).idle(); + assertThat(mPreference.getSummary().toString()) + .isEqualTo( + mContext.getString( + R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); + } + + @Test + public void displayPreference_fallbackDeviceInSharing_showCorrectSummary() { Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice2.getDevice()).thenReturn(mDevice2); - when(mCachedDevice1.getMemberDevice()).thenReturn(ImmutableSet.of(mCachedDevice2)); - when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); - when(mCachedDevice3.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); - when(mCachedDevice3.getDevice()).thenReturn(mDevice3); - when(mCachedDevice3.getName()).thenReturn(TEST_DEVICE_NAME2); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); - when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); - when(mCacheManager.findDevice(mDevice3)).thenReturn(mCachedDevice3); + when(mCachedDevice3.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); when(mBroadcast.isEnabled(any())).thenReturn(true); when(mAssistant.getAllConnectedDevices()) .thenReturn(ImmutableList.of(mDevice1, mDevice2, mDevice3)); @@ -379,14 +405,24 @@ public class AudioSharingCallAudioPreferenceControllerTest { } @Test - public void displayPreference_noFallbackDeviceInSharing_showEmptySummary() { + public void displayPreference_activeDeviceInSharing_showCorrectSummary() { Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID2); - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); + when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true); when(mBroadcast.isEnabled(any())).thenReturn(true); - when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); + when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); + when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); + mController.displayPreference(mScreen); + shadowOf(Looper.getMainLooper()).idle(); + assertThat(mPreference.getSummary().toString()) + .isEqualTo(mContext.getString( + R.string.audio_sharing_call_audio_description, TEST_DEVICE_NAME1)); + } + + @Test + public void displayPreference_noFallbackDeviceOrActiveInSharing_showEmptySummary() { + Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID2); + when(mBroadcast.isEnabled(any())).thenReturn(true); + when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); mController.displayPreference(mScreen); shadowOf(Looper.getMainLooper()).idle(); @@ -394,7 +430,7 @@ public class AudioSharingCallAudioPreferenceControllerTest { } @Test - public void displayPreference_noFallbackDevice_showEmptySummary() { + public void displayPreference_noFallbackOrActiveDevice_showEmptySummary() { Settings.Secure.putInt( mContentResolver, TEST_SETTINGS_KEY, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); when(mBroadcast.isEnabled(any())).thenReturn(true); @@ -412,17 +448,11 @@ public class AudioSharingCallAudioPreferenceControllerTest { ShadowAlertDialogCompat.reset(); } Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); - when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME2); - when(mCachedDevice2.getDevice()).thenReturn(mDevice2); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); - when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); - mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1, mDevice2)); + mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( + List.of(mDevice1, mDevice2, mDevice3)); when(mBroadcast.isEnabled(any())).thenReturn(true); - when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1, mDevice2)); + when(mAssistant.getAllConnectedDevices()).thenReturn( + ImmutableList.of(mDevice1, mDevice2, mDevice3)); when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); mController.init(mParentFragment); mController.displayPreference(mScreen); @@ -449,14 +479,9 @@ public class AudioSharingCallAudioPreferenceControllerTest { @Test public void logCallAudioDeviceChange_changeCallAudioToEarlierConnectedDevice() { - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); - when(mCachedDevice2.getDevice()).thenReturn(mDevice2); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); - when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); - mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1, mDevice2)); - mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID1, mCachedDevice2); + mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( + List.of(mDevice1, mDevice2, mDevice3)); + mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID1, mCachedDevice3); verify(mFeatureFactory.metricsFeatureProvider) .action( mContext, @@ -468,13 +493,8 @@ public class AudioSharingCallAudioPreferenceControllerTest { @Test public void logCallAudioDeviceChange_changeCallAudioToLaterConnectedDevice() { - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); - when(mCachedDevice2.getDevice()).thenReturn(mDevice2); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); - when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); - mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1, mDevice2)); + mShadowBluetoothAdapter.setMostRecentlyConnectedDevices( + List.of(mDevice1, mDevice2, mDevice3)); mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID2, mCachedDevice1); verify(mFeatureFactory.metricsFeatureProvider) .action( @@ -487,14 +507,8 @@ public class AudioSharingCallAudioPreferenceControllerTest { @Test public void logCallAudioDeviceChange_deviceNotFoundInRecentList_unknownChangeType() { - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2); - when(mCachedDevice2.getDevice()).thenReturn(mDevice2); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); - when(mCacheManager.findDevice(mDevice2)).thenReturn(mCachedDevice2); - mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1)); - mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID1, mCachedDevice2); + mShadowBluetoothAdapter.setMostRecentlyConnectedDevices(List.of(mDevice1, mDevice2)); + mController.logCallAudioDeviceChange(TEST_DEVICE_GROUP_ID1, mCachedDevice3); verify(mFeatureFactory.metricsFeatureProvider) .action( mContext, @@ -505,10 +519,6 @@ public class AudioSharingCallAudioPreferenceControllerTest { @Test public void testBluetoothLeBroadcastAssistantCallbacks_updateSummary() { - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); Settings.Secure.putInt( mContentResolver, TEST_SETTINGS_KEY, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); when(mBroadcast.isEnabled(any())).thenReturn(true); @@ -532,10 +542,6 @@ public class AudioSharingCallAudioPreferenceControllerTest { @Test public void testBluetoothLeBroadcastAssistantCallbacks_doNothing() { - when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1); - when(mCachedDevice1.getDevice()).thenReturn(mDevice1); - when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1); - when(mCacheManager.findDevice(mDevice1)).thenReturn(mCachedDevice1); Settings.Secure.putInt( mContentResolver, TEST_SETTINGS_KEY, BluetoothCsipSetCoordinator.GROUP_ID_INVALID); when(mBroadcast.isEnabled(any())).thenReturn(true); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItemTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItemTest.java index b23882d3953..27bff7644b6 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItemTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceItemTest.java @@ -78,4 +78,13 @@ public class AudioSharingDeviceItemTest { assertThat(itemFromParcel.getGroupId()).isEqualTo(TEST_GROUP_ID); assertThat(itemFromParcel.isActive()).isEqualTo(TEST_IS_ACTIVE); } + + @Test + public void toString_correctValue() { + AudioSharingDeviceItem item = + new AudioSharingDeviceItem(TEST_NAME, TEST_GROUP_ID, TEST_IS_ACTIVE); + assertThat(item.toString()).isEqualTo( + "AudioSharingDeviceItem groupId = " + TEST_GROUP_ID + ", isActive = " + + TEST_IS_ACTIVE); + } }