Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b845003a authored by Wenyu Zhang's avatar Wenyu Zhang
Browse files

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
parent bc57d803
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -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 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;
@@ -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;
@@ -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);
@@ -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;
@@ -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;
@@ -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.
+35 −0
Original line number Diff line number Diff line
@@ -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 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"

@@ -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())
@@ -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) {
+6 −1
Original line number Diff line number Diff line
@@ -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 @@ 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,
@@ -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 {
+2 −0
Original line number Diff line number Diff line
@@ -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 @@ import com.android.systemui.volume.mediaOutputInteractor
val Kosmos.mediaOutputComponentInteractor by
    Kosmos.Fixture {
        MediaOutputComponentInteractor(
            mockedContext,
            testScope.backgroundScope,
            mediaDeviceSessionInteractor,
            audioOutputInteractor,