Allow users to open switcher in call for desktop
When input routing is enabled in desktop devices, allow users to open
switcher dialog during call/meeting.
Change-Id: Ia88352a4fb1619b08f86710cf21557fb3df7479a
Bug: b/355684672, b/357123258
Test: atest MediaOutputComponentInteractorTest
Flag: com.android.media.flags.enable_audio_input_device_routing_and_volume_control
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index feaf7fb..b94e906 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -15,6 +15,7 @@
*/
package com.android.settingslib.media;
+import static android.content.pm.PackageManager.FEATURE_PC;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_HDMI;
@@ -29,8 +30,6 @@
import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
@@ -43,6 +42,8 @@
import android.util.Log;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.settingslib.R;
import com.android.settingslib.media.flags.Flags;
@@ -72,7 +73,7 @@
return context.getString(R.string.media_transfer_this_device_name_tv);
} else if (isTablet()) {
return context.getString(R.string.media_transfer_this_device_name_tablet);
- } else if (inputRoutingEnabledAndIsDesktop()) {
+ } else if (inputRoutingEnabledAndIsDesktop(context)) {
return context.getString(R.string.media_transfer_this_device_name_desktop);
} else {
return context.getString(R.string.media_transfer_this_device_name);
@@ -88,7 +89,7 @@
case TYPE_WIRED_HEADSET:
case TYPE_WIRED_HEADPHONES:
name =
- inputRoutingEnabledAndIsDesktop()
+ inputRoutingEnabledAndIsDesktop(context)
? context.getString(R.string.media_transfer_headphone_name)
: context.getString(R.string.media_transfer_wired_headphone_name);
break;
@@ -96,7 +97,7 @@
case TYPE_USB_HEADSET:
case TYPE_USB_ACCESSORY:
name =
- inputRoutingEnabledAndIsDesktop()
+ inputRoutingEnabledAndIsDesktop(context)
? context.getString(R.string.media_transfer_usb_audio_name)
: context.getString(R.string.media_transfer_wired_headphone_name);
break;
@@ -149,14 +150,13 @@
.contains("tablet");
}
- static boolean isDesktop() {
- return Arrays.asList(SystemProperties.get("ro.build.characteristics").split(","))
- .contains("desktop");
+ public static boolean isDesktop(@NonNull Context context) {
+ return context.getPackageManager().hasSystemFeature(FEATURE_PC);
}
- static boolean inputRoutingEnabledAndIsDesktop() {
+ public static boolean inputRoutingEnabledAndIsDesktop(@NonNull Context context) {
return com.android.media.flags.Flags.enableAudioInputDeviceRoutingAndVolumeControl()
- && isDesktop();
+ && isDesktop(context);
}
// MediaRoute2Info.getType was made public on API 34, but exists since API 30.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt
index fa7f37c..449dc20 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt
@@ -16,11 +16,16 @@
package com.android.systemui.volume.panel.component.mediaoutput.domain.interactor
+import android.content.mockedContext
+import android.content.packageManager
+import android.content.pm.PackageManager.FEATURE_PC
import android.graphics.drawable.TestStubDrawable
import android.media.AudioManager
+import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.media.flags.Flags;
import com.android.settingslib.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -42,6 +47,7 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.whenever
private const val builtInDeviceName = "This phone"
@@ -79,6 +85,8 @@
fun inCall_stateIs_Calling() =
with(kosmos) {
testScope.runTest {
+ whenever(mockedContext.getPackageManager()).thenReturn(packageManager)
+ whenever(packageManager.hasSystemFeature(FEATURE_PC)).thenReturn(false)
with(audioRepository) {
setMode(AudioManager.MODE_IN_CALL)
setCommunicationDevice(TestAudioDevicesFactory.builtInDevice())
@@ -98,6 +106,33 @@
}
}
+ @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+ @Test
+ fun inCall_stateIs_Calling_enableInputRouting_desktop() =
+ with(kosmos) {
+ testScope.runTest {
+ whenever(mockedContext.getPackageManager()).thenReturn(packageManager)
+ whenever(packageManager.hasSystemFeature(FEATURE_PC)).thenReturn(true)
+
+ with(audioRepository) {
+ setMode(AudioManager.MODE_IN_CALL)
+ setCommunicationDevice(TestAudioDevicesFactory.builtInDevice())
+ }
+
+ val model by collectLastValue(underTest.mediaOutputModel.filterData())
+ runCurrent()
+
+ assertThat(model)
+ .isEqualTo(
+ MediaOutputComponentModel.Calling(
+ device = AudioOutputDevice.BuiltIn(builtInDeviceName, testIcon),
+ isInAudioSharing = false,
+ canOpenAudioSwitcher = true,
+ )
+ )
+ }
+ }
+
@Test
fun hasSession_stateIs_MediaSession() =
with(kosmos) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractor.kt
index f94cbda..609ba02 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractor.kt
@@ -16,7 +16,10 @@
package com.android.systemui.volume.panel.component.mediaoutput.domain.interactor
+import com.android.settingslib.media.PhoneMediaDevice.inputRoutingEnabledAndIsDesktop
+import android.content.Context
import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.volume.domain.interactor.AudioOutputInteractor
import com.android.systemui.volume.domain.interactor.AudioSharingInteractor
import com.android.systemui.volume.domain.model.AudioOutputDevice
@@ -46,6 +49,7 @@
class MediaOutputComponentInteractor
@Inject
constructor(
+ @Application private val context: Context,
@VolumePanelScope private val coroutineScope: CoroutineScope,
private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor,
audioOutputInteractor: AudioOutputInteractor,
@@ -91,7 +95,8 @@
MediaOutputComponentModel.Calling(
device = currentAudioDevice,
isInAudioSharing = isInAudioSharing,
- canOpenAudioSwitcher = false,
+ /* allow open switcher when input routing is enabled in desktop */
+ canOpenAudioSwitcher = inputRoutingEnabledAndIsDesktop(context),
)
)
} else {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorKosmos.kt
index 63a1325..db66c3e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.panel.component.mediaoutput.domain.interactor
+import android.content.mockedContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.volume.domain.interactor.audioModeInteractor
@@ -27,6 +28,7 @@
val Kosmos.mediaOutputComponentInteractor by
Kosmos.Fixture {
MediaOutputComponentInteractor(
+ mockedContext,
testScope.backgroundScope,
mediaDeviceSessionInteractor,
audioOutputInteractor,