Loading packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +10 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -29,8 +30,6 @@ import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; 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; Loading @@ -43,6 +42,8 @@ import android.os.SystemProperties; 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; Loading Loading @@ -72,7 +73,7 @@ public class PhoneMediaDevice extends MediaDevice { 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); Loading @@ -88,7 +89,7 @@ public class PhoneMediaDevice extends MediaDevice { 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; Loading @@ -96,7 +97,7 @@ public class PhoneMediaDevice extends MediaDevice { 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; Loading Loading @@ -149,14 +150,13 @@ public class PhoneMediaDevice extends MediaDevice { .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. Loading packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt +35 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -42,6 +47,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.whenever private const val builtInDeviceName = "This phone" Loading Loading @@ -79,6 +85,8 @@ class MediaOutputComponentInteractorTest : SysuiTestCase() { 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()) Loading @@ -98,6 +106,33 @@ class MediaOutputComponentInteractorTest : SysuiTestCase() { } } @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) { Loading packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractor.kt +6 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -46,6 +49,7 @@ import kotlinx.coroutines.flow.stateIn class MediaOutputComponentInteractor @Inject constructor( @Application private val context: Context, @VolumePanelScope private val coroutineScope: CoroutineScope, private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, audioOutputInteractor: AudioOutputInteractor, Loading Loading @@ -91,7 +95,8 @@ constructor( MediaOutputComponentModel.Calling( device = currentAudioDevice, isInAudioSharing = isInAudioSharing, canOpenAudioSwitcher = false, /* allow open switcher when input routing is enabled in desktop */ canOpenAudioSwitcher = inputRoutingEnabledAndIsDesktop(context), ) ) } else { Loading packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -27,6 +28,7 @@ import com.android.systemui.volume.mediaOutputInteractor val Kosmos.mediaOutputComponentInteractor by Kosmos.Fixture { MediaOutputComponentInteractor( mockedContext, testScope.backgroundScope, mediaDeviceSessionInteractor, audioOutputInteractor, Loading Loading
packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java +10 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -29,8 +30,6 @@ import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET; 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; Loading @@ -43,6 +42,8 @@ import android.os.SystemProperties; 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; Loading Loading @@ -72,7 +73,7 @@ public class PhoneMediaDevice extends MediaDevice { 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); Loading @@ -88,7 +89,7 @@ public class PhoneMediaDevice extends MediaDevice { 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; Loading @@ -96,7 +97,7 @@ public class PhoneMediaDevice extends MediaDevice { 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; Loading Loading @@ -149,14 +150,13 @@ public class PhoneMediaDevice extends MediaDevice { .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. Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorTest.kt +35 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -42,6 +47,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.whenever private const val builtInDeviceName = "This phone" Loading Loading @@ -79,6 +85,8 @@ class MediaOutputComponentInteractorTest : SysuiTestCase() { 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()) Loading @@ -98,6 +106,33 @@ class MediaOutputComponentInteractorTest : SysuiTestCase() { } } @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) { Loading
packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractor.kt +6 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -46,6 +49,7 @@ import kotlinx.coroutines.flow.stateIn class MediaOutputComponentInteractor @Inject constructor( @Application private val context: Context, @VolumePanelScope private val coroutineScope: CoroutineScope, private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, audioOutputInteractor: AudioOutputInteractor, Loading Loading @@ -91,7 +95,8 @@ constructor( MediaOutputComponentModel.Calling( device = currentAudioDevice, isInAudioSharing = isInAudioSharing, canOpenAudioSwitcher = false, /* allow open switcher when input routing is enabled in desktop */ canOpenAudioSwitcher = inputRoutingEnabledAndIsDesktop(context), ) ) } else { Loading
packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputComponentInteractorKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -27,6 +28,7 @@ import com.android.systemui.volume.mediaOutputInteractor val Kosmos.mediaOutputComponentInteractor by Kosmos.Fixture { MediaOutputComponentInteractor( mockedContext, testScope.backgroundScope, mediaDeviceSessionInteractor, audioOutputInteractor, Loading