summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java94
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt109
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt17
8 files changed, 204 insertions, 90 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
index e4539b75f317..0b13900d826b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -45,7 +45,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
-import android.os.Handler;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
@@ -75,6 +74,8 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.phone.SystemUIDialogManager;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.After;
import org.junit.Before;
@@ -107,6 +108,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
private static final String TEST_LABEL = "label";
private static final int TEST_PRESET_INDEX = 1;
private static final String TEST_PRESET_NAME = "test_preset";
+ private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
@Mock
private SystemUIDialogManager mSystemUIDialogManager;
@@ -150,11 +152,9 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
private SystemUIDialog mDialog;
private SystemUIDialog.Factory mDialogFactory;
private HearingDevicesDialogDelegate mDialogDelegate;
- private TestableLooper mTestableLooper;
@Before
public void setUp() {
- mTestableLooper = TestableLooper.get(this);
when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
@@ -186,6 +186,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
public void clickPairNewDeviceButton_intentActionMatch() {
setUpDeviceDialogWithPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
getPairNewDeviceButton(mDialog).performClick();
@@ -232,6 +233,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
assertToolsUi(0);
}
@@ -246,6 +248,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
assertToolsUi(1);
}
@@ -267,6 +270,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
assertToolsUi(2);
}
@@ -278,6 +282,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
ViewGroup presetLayout = getPresetLayout(mDialog);
assertThat(presetLayout.getVisibility()).isEqualTo(View.GONE);
@@ -291,7 +296,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
- mTestableLooper.processAllMessages();
+ mExecutor.runAllReady();
ViewGroup presetLayout = getPresetLayout(mDialog);
assertThat(presetLayout.getVisibility()).isEqualTo(View.VISIBLE);
@@ -306,6 +311,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
ViewGroup ambientLayout = getAmbientLayout(mDialog);
assertThat(ambientLayout.getVisibility()).isEqualTo(View.GONE);
@@ -318,6 +324,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
ViewGroup ambientLayout = getAmbientLayout(mDialog);
assertThat(ambientLayout.getVisibility()).isEqualTo(View.GONE);
@@ -343,6 +350,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
public void onActiveDeviceChanged_presetExist_presetSelected() {
setUpDeviceDialogWithoutPairNewDeviceButton();
mDialog.show();
+ mExecutor.runAllReady();
BluetoothHapPresetInfo info = getTestPresetInfo();
when(mHapClientProfile.getAllPresetInfo(mDevice)).thenReturn(List.of(info));
when(mHapClientProfile.getActivePresetIndex(mDevice)).thenReturn(TEST_PRESET_INDEX);
@@ -351,7 +359,7 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
assertThat(spinner.getSelectedItemPosition()).isEqualTo(-1);
mDialogDelegate.onActiveDeviceChanged(mCachedDevice, BluetoothProfile.LE_AUDIO);
- mTestableLooper.processAllMessages();
+ mExecutor.runAllReady();
ViewGroup presetLayout = getPresetLayout(mDialog);
assertThat(presetLayout.getVisibility()).isEqualTo(View.VISIBLE);
@@ -381,7 +389,8 @@ public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
mActivityStarter,
mDialogTransitionAnimator,
mLocalBluetoothManager,
- new Handler(mTestableLooper.getLooper()),
+ mExecutor,
+ mExecutor,
mAudioManager,
mUiEventLogger
);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index 438184d4d2d6..22ecb0af8c18 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -30,7 +30,6 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Bundle;
-import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
@@ -49,6 +48,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -57,7 +57,6 @@ import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.accessibility.hearingaid.HearingDevicesListAdapter.HearingDeviceItemCallback;
import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.bluetooth.qsdialog.ActiveHearingDeviceItemFactory;
@@ -67,6 +66,7 @@ import com.android.systemui.bluetooth.qsdialog.DeviceItem;
import com.android.systemui.bluetooth.qsdialog.DeviceItemFactory;
import com.android.systemui.bluetooth.qsdialog.DeviceItemType;
import com.android.systemui.bluetooth.qsdialog.SavedHearingDeviceItemFactory;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.res.R;
@@ -79,6 +79,7 @@ import dagger.assisted.AssistedInject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.Executor;
import java.util.stream.Collectors;
/**
@@ -101,7 +102,8 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
private final DialogTransitionAnimator mDialogTransitionAnimator;
private final ActivityStarter mActivityStarter;
private final LocalBluetoothManager mLocalBluetoothManager;
- private final Handler mMainHandler;
+ private final Executor mMainExecutor;
+ private final Executor mBgExecutor;
private final AudioManager mAudioManager;
private final LocalBluetoothProfileManager mProfileManager;
private final HearingDevicesUiEventLogger mUiEventLogger;
@@ -109,8 +111,6 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
private final int mLaunchSourceId;
private SystemUIDialog mDialog;
-
- private List<DeviceItem> mHearingDeviceItemList;
private HearingDevicesListAdapter mDeviceListAdapter;
private View mPresetLayout;
@@ -122,14 +122,14 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
@Override
public void onPresetInfoUpdated(List<BluetoothHapPresetInfo> presetInfos,
int activePresetIndex) {
- mMainHandler.post(
+ mMainExecutor.execute(
() -> refreshPresetUi(presetInfos, activePresetIndex));
}
@Override
public void onPresetCommandFailed(int reason) {
mPresetController.refreshPresetInfo();
- mMainHandler.post(() -> {
+ mMainExecutor.execute(() -> {
showErrorToast(R.string.hearing_devices_presets_error);
});
}
@@ -166,7 +166,8 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
ActivityStarter activityStarter,
DialogTransitionAnimator dialogTransitionAnimator,
@Nullable LocalBluetoothManager localBluetoothManager,
- @Main Handler handler,
+ @Main Executor mainExecutor,
+ @Background Executor bgExecutor,
AudioManager audioManager,
HearingDevicesUiEventLogger uiEventLogger) {
mShowPairNewDevice = showPairNewDevice;
@@ -174,7 +175,8 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
mActivityStarter = activityStarter;
mDialogTransitionAnimator = dialogTransitionAnimator;
mLocalBluetoothManager = localBluetoothManager;
- mMainHandler = handler;
+ mMainExecutor = mainExecutor;
+ mBgExecutor = bgExecutor;
mAudioManager = audioManager;
mProfileManager = localBluetoothManager.getProfileManager();
mUiEventLogger = uiEventLogger;
@@ -227,9 +229,10 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
@Override
public void onActiveDeviceChanged(@Nullable CachedBluetoothDevice activeDevice,
int bluetoothProfile) {
- refreshDeviceUi();
- mMainHandler.post(() -> {
- CachedBluetoothDevice device = getActiveHearingDevice();
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ refreshDeviceUi(hearingDeviceItemList);
+ mMainExecutor.execute(() -> {
+ CachedBluetoothDevice device = getActiveHearingDevice(hearingDeviceItemList);
if (mPresetController != null) {
mPresetController.setDevice(device);
mPresetLayout.setVisibility(
@@ -244,13 +247,15 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
@Override
public void onProfileConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
int state, int bluetoothProfile) {
- refreshDeviceUi();
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ refreshDeviceUi(hearingDeviceItemList);
}
@Override
public void onAclConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
int state) {
- refreshDeviceUi();
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ refreshDeviceUi(hearingDeviceItemList);
}
@Override
@@ -280,18 +285,25 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_DIALOG_SHOW, mLaunchSourceId);
- setupDeviceListView(dialog);
- setupPairNewDeviceButton(dialog);
- setupPresetSpinner(dialog);
- if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) {
- setupAmbientControls();
- }
- setupRelatedToolsView(dialog);
+ mBgExecutor.execute(() -> {
+ List<DeviceItem> hearingDeviceItemList = getHearingDeviceItemList();
+ CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice(
+ hearingDeviceItemList);
+ mMainExecutor.execute(() -> {
+ setupDeviceListView(dialog, hearingDeviceItemList);
+ setupPairNewDeviceButton(dialog);
+ setupPresetSpinner(dialog, activeHearingDevice);
+ if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) {
+ setupAmbientControls(activeHearingDevice);
+ }
+ setupRelatedToolsView(dialog);
+ });
+ });
}
@Override
public void onStart(@NonNull SystemUIDialog dialog) {
- ThreadUtils.postOnBackgroundThread(() -> {
+ mBgExecutor.execute(() -> {
if (mLocalBluetoothManager != null) {
mLocalBluetoothManager.getEventManager().registerCallback(this);
}
@@ -306,7 +318,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
@Override
public void onStop(@NonNull SystemUIDialog dialog) {
- ThreadUtils.postOnBackgroundThread(() -> {
+ mBgExecutor.execute(() -> {
if (mLocalBluetoothManager != null) {
mLocalBluetoothManager.getEventManager().unregisterCallback(this);
}
@@ -319,17 +331,18 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
});
}
- private void setupDeviceListView(SystemUIDialog dialog) {
+ private void setupDeviceListView(SystemUIDialog dialog,
+ List<DeviceItem> hearingDeviceItemList) {
final RecyclerView deviceList = dialog.requireViewById(R.id.device_list);
deviceList.setLayoutManager(new LinearLayoutManager(dialog.getContext()));
- mHearingDeviceItemList = getHearingDeviceItemList();
- mDeviceListAdapter = new HearingDevicesListAdapter(mHearingDeviceItemList, this);
+ mDeviceListAdapter = new HearingDevicesListAdapter(hearingDeviceItemList, this);
deviceList.setAdapter(mDeviceListAdapter);
}
- private void setupPresetSpinner(SystemUIDialog dialog) {
+ private void setupPresetSpinner(SystemUIDialog dialog,
+ CachedBluetoothDevice activeHearingDevice) {
mPresetController = new HearingDevicesPresetsController(mProfileManager, mPresetCallback);
- mPresetController.setDevice(getActiveHearingDevice());
+ mPresetController.setDevice(activeHearingDevice);
mPresetSpinner = dialog.requireViewById(R.id.preset_spinner);
mPresetInfoAdapter = new HearingDevicesSpinnerAdapter(dialog.getContext());
@@ -367,12 +380,12 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
mPresetLayout.setVisibility(mPresetController.isPresetControlAvailable() ? VISIBLE : GONE);
}
- private void setupAmbientControls() {
+ private void setupAmbientControls(CachedBluetoothDevice activeHearingDevice) {
final AmbientVolumeLayout ambientLayout = mDialog.requireViewById(R.id.ambient_layout);
mAmbientController = new AmbientVolumeUiController(
mDialog.getContext(), mLocalBluetoothManager, ambientLayout);
mAmbientController.setShowUiWhenLocalDataExist(false);
- mAmbientController.loadDevice(getActiveHearingDevice());
+ mAmbientController.loadDevice(activeHearingDevice);
}
private void setupPairNewDeviceButton(SystemUIDialog dialog) {
@@ -429,10 +442,11 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
}
}
- private void refreshDeviceUi() {
- mHearingDeviceItemList = getHearingDeviceItemList();
- mMainHandler.post(() -> {
- mDeviceListAdapter.refreshDeviceItemList(mHearingDeviceItemList);
+ private void refreshDeviceUi(List<DeviceItem> hearingDeviceItemList) {
+ mMainExecutor.execute(() -> {
+ if (mDeviceListAdapter != null) {
+ mDeviceListAdapter.refreshDeviceItemList(hearingDeviceItemList);
+ }
});
}
@@ -463,21 +477,27 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
}
@Nullable
- private CachedBluetoothDevice getActiveHearingDevice() {
- return mHearingDeviceItemList.stream()
+ private static CachedBluetoothDevice getActiveHearingDevice(
+ List<DeviceItem> hearingDeviceItemList) {
+ return hearingDeviceItemList.stream()
.filter(item -> item.getType() == DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
.map(DeviceItem::getCachedBluetoothDevice)
.findFirst()
.orElse(null);
}
+ @WorkerThread
private DeviceItem createHearingDeviceItem(CachedBluetoothDevice cachedDevice) {
final Context context = mDialog.getContext();
if (cachedDevice == null) {
return null;
}
+ int mode = mAudioManager.getMode();
+ boolean isOngoingCall = mode == AudioManager.MODE_RINGTONE
+ || mode == AudioManager.MODE_IN_CALL
+ || mode == AudioManager.MODE_IN_COMMUNICATION;
for (DeviceItemFactory itemFactory : mHearingDeviceItemFactoryList) {
- if (itemFactory.isFilterMatched(context, cachedDevice, mAudioManager)) {
+ if (itemFactory.isFilterMatched(context, cachedDevice, isOngoingCall)) {
return itemFactory.create(context, cachedDevice);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
index ff2d9efa1b58..1c9cf8d14f74 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModel.kt
@@ -31,6 +31,7 @@ import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
+import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.systemui.Prefs
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
@@ -71,6 +72,7 @@ constructor(
private val bluetoothStateInteractor: BluetoothStateInteractor,
private val bluetoothAutoOnInteractor: BluetoothAutoOnInteractor,
private val audioSharingInteractor: AudioSharingInteractor,
+ private val audioModeInteractor: AudioModeInteractor,
private val audioSharingButtonViewModelFactory: AudioSharingButtonViewModel.Factory,
private val bluetoothDeviceMetadataInteractor: BluetoothDeviceMetadataInteractor,
private val dialogTransitionAnimator: DialogTransitionAnimator,
@@ -167,6 +169,7 @@ constructor(
// the device item list and animate the progress bar.
merge(
deviceItemInteractor.deviceItemUpdateRequest,
+ audioModeInteractor.isOngoingCall,
bluetoothDeviceMetadataInteractor.metadataUpdate,
if (
audioSharingInteractor.audioSharingAvailable() &&
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
index 095e6e741584..bfbc27d3a086 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
@@ -18,7 +18,6 @@ package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothDevice
import android.content.Context
-import android.media.AudioManager
import com.android.settingslib.bluetooth.BluetoothUtils
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -43,7 +42,7 @@ abstract class DeviceItemFactory {
abstract fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean
@@ -51,8 +50,8 @@ abstract class DeviceItemFactory {
fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
- ): Boolean = isFilterMatched(context, cachedDevice, audioManager, false)
+ isOngoingCall: Boolean,
+ ): Boolean = isFilterMatched(context, cachedDevice, isOngoingCall, false)
abstract fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem
@@ -88,11 +87,11 @@ internal open class ActiveMediaDeviceItemFactory : DeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
- BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, isOngoingCall)
}
override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
@@ -113,10 +112,11 @@ internal class AudioSharingMediaDeviceItemFactory(
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return audioSharingAvailable &&
+ !isOngoingCall &&
BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, localBluetoothManager)
}
@@ -140,11 +140,12 @@ internal class AvailableAudioSharingMediaDeviceItemFactory(
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return audioSharingAvailable &&
- super.isFilterMatched(context, cachedDevice, audioManager, true) &&
+ !isOngoingCall &&
+ super.isFilterMatched(context, cachedDevice, false, true) &&
BluetoothUtils.isAvailableAudioSharingMediaBluetoothDevice(
cachedDevice,
localBluetoothManager,
@@ -170,7 +171,7 @@ internal class ActiveHearingDeviceItemFactory : ActiveMediaDeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
@@ -182,11 +183,11 @@ open class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
- BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, isOngoingCall)
}
override fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem {
@@ -206,7 +207,7 @@ internal class AvailableHearingDeviceItemFactory : AvailableMediaDeviceItemFacto
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
@@ -218,14 +219,14 @@ internal class ConnectedDeviceItemFactory : DeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
!BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
- BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, isOngoingCall)
} else {
- BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, audioManager)
+ BluetoothUtils.isConnectedBluetoothDevice(cachedDevice, isOngoingCall)
}
}
@@ -246,7 +247,7 @@ internal open class SavedDeviceItemFactory : DeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
@@ -275,7 +276,7 @@ internal class SavedHearingDeviceItemFactory : SavedDeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
): Boolean {
return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
index 1e0ba8e75714..b606c19b3503 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
@@ -19,10 +19,10 @@ package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.Context
-import android.media.AudioManager
import com.android.settingslib.bluetooth.BluetoothCallback
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
@@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.isActive
@@ -51,7 +52,6 @@ class DeviceItemInteractor
constructor(
private val bluetoothTileDialogRepository: BluetoothTileDialogRepository,
private val audioSharingInteractor: AudioSharingInteractor,
- private val audioManager: AudioManager,
private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(),
private val localBluetoothManager: LocalBluetoothManager?,
private val systemClock: SystemClock,
@@ -60,6 +60,7 @@ constructor(
private val deviceItemDisplayPriority: List<@JvmSuppressWildcards DeviceItemType>,
@Application private val coroutineScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
+ private val audioModeInteractor: AudioModeInteractor,
) {
private val mutableDeviceItemUpdate: MutableSharedFlow<List<DeviceItem>> =
@@ -118,8 +119,12 @@ constructor(
internal suspend fun updateDeviceItems(context: Context, trigger: DeviceFetchTrigger) {
withContext(backgroundDispatcher) {
+ if (!isActive) {
+ return@withContext
+ }
val start = systemClock.elapsedRealtime()
val audioSharingAvailable = audioSharingInteractor.audioSharingAvailable()
+ val isOngoingCall = audioModeInteractor.isOngoingCall.first()
val deviceItems =
bluetoothTileDialogRepository.cachedDevices
.mapNotNull { cachedDevice ->
@@ -128,7 +133,7 @@ constructor(
it.isFilterMatched(
context,
cachedDevice,
- audioManager,
+ isOngoingCall,
audioSharingAvailable,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt
index bfc5361b6129..f04fc86d7230 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDetailsContentViewModelTest.kt
@@ -43,6 +43,7 @@ import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -146,6 +147,7 @@ class BluetoothDetailsContentViewModelTest : SysuiTestCase() {
)
),
kosmos.audioSharingInteractor,
+ kosmos.audioModeInteractor,
kosmos.audioSharingButtonViewModelFactory,
bluetoothDeviceMetadataInteractor,
mDialogTransitionAnimator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
index 0aa5199cb20e..7c8822bc11ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
@@ -18,7 +18,6 @@ package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothDevice
import android.graphics.drawable.Drawable
-import android.media.AudioManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
@@ -61,8 +60,6 @@ class DeviceItemFactoryTest : SysuiTestCase() {
private val connectedDeviceItemFactory = ConnectedDeviceItemFactory()
private val savedDeviceItemFactory = SavedDeviceItemFactory()
- private val audioManager = context.getSystemService(AudioManager::class.java)!!
-
@Before
fun setup() {
mockitoSession =
@@ -132,7 +129,12 @@ class DeviceItemFactoryTest : SysuiTestCase() {
fun testAvailableAudioSharingMediaDeviceItemFactory_isFilterMatched_flagOff_returnsFalse() {
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, false)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = false,
+ )
)
.isFalse()
}
@@ -143,7 +145,12 @@ class DeviceItemFactoryTest : SysuiTestCase() {
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, true)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = true,
+ )
)
.isFalse()
}
@@ -157,7 +164,26 @@ class DeviceItemFactoryTest : SysuiTestCase() {
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, true)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = true,
+ )
+ )
+ .isFalse()
+ }
+
+ @Test
+ fun testAvailableAudioSharingMediaDeviceItemFactory_isFilterMatched_inCall_false() {
+ assertThat(
+ AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = true,
+ audioSharingAvailable = true,
+ )
)
.isFalse()
}
@@ -171,7 +197,12 @@ class DeviceItemFactoryTest : SysuiTestCase() {
assertThat(
AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)
- .isFilterMatched(context, cachedDevice, audioManager, true)
+ .isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ audioSharingAvailable = true,
+ )
)
.isTrue()
}
@@ -182,7 +213,9 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(false)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isTrue()
}
@@ -192,7 +225,9 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(true)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -201,7 +236,9 @@ class DeviceItemFactoryTest : SysuiTestCase() {
fun testSavedFactory_isFilterMatched_notBonded_returnsFalse() {
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_NONE)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -211,7 +248,9 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -223,7 +262,9 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(false)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isTrue()
}
@@ -235,7 +276,9 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(cachedDevice.bondState).thenReturn(BluetoothDevice.BOND_BONDED)
`when`(cachedDevice.isConnected).thenReturn(true)
- assertThat(savedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ savedDeviceItemFactory.isFilterMatched(context, cachedDevice, isOngoingCall = false)
+ )
.isFalse()
}
@@ -244,14 +287,26 @@ class DeviceItemFactoryTest : SysuiTestCase() {
fun testConnectedFactory_isFilterMatched_bondedAndConnected_returnsTrue() {
`when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isTrue()
}
@Test
@DisableFlags(Flags.FLAG_ENABLE_HIDE_EXCLUSIVELY_MANAGED_BLUETOOTH_DEVICE)
fun testConnectedFactory_isFilterMatched_notConnected_returnsFalse() {
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isFalse()
}
@@ -261,7 +316,13 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(cachedDevice.device).thenReturn(bluetoothDevice)
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isFalse()
}
@@ -272,7 +333,13 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
`when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(true)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isTrue()
}
@@ -283,7 +350,13 @@ class DeviceItemFactoryTest : SysuiTestCase() {
`when`(BluetoothUtils.isExclusivelyManagedBluetoothDevice(any(), any())).thenReturn(false)
`when`(BluetoothUtils.isConnectedBluetoothDevice(any(), any())).thenReturn(false)
- assertThat(connectedDeviceItemFactory.isFilterMatched(context, cachedDevice, audioManager))
+ assertThat(
+ connectedDeviceItemFactory.isFilterMatched(
+ context,
+ cachedDevice,
+ isOngoingCall = false,
+ )
+ )
.isFalse()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
index 42dc50d77d05..943b89aa10f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
@@ -29,6 +29,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.testKosmos
import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.test.TestScope
@@ -102,7 +103,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -111,6 +111,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -130,7 +131,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -139,6 +139,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -158,7 +159,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -167,6 +167,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -186,7 +187,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -198,6 +198,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
@@ -217,7 +218,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -238,6 +238,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
`when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
`when`(deviceItem2.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
@@ -259,7 +260,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -277,6 +277,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
listOf(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
`when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
`when`(deviceItem2.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
@@ -300,7 +301,6 @@ class DeviceItemInteractorTest : SysuiTestCase() {
DeviceItemInteractor(
bluetoothTileDialogRepository,
kosmos.audioSharingInteractor,
- audioManager,
adapter,
localBluetoothManager,
fakeSystemClock,
@@ -309,6 +309,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
emptyList(),
testScope.backgroundScope,
dispatcher,
+ kosmos.audioModeInteractor,
)
val latest by collectLastValue(interactor.deviceItemUpdate)
val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
@@ -327,7 +328,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
- audioManager: AudioManager,
+ isOngoingCall: Boolean,
audioSharingAvailable: Boolean,
) = isFilterMatchFunc(cachedDevice)