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

Commit 72193d53 authored by Michael Mikhail's avatar Michael Mikhail
Browse files

implement media outputSwitcher clicks

Flag: com.android.systemui.media_controls_in_compose
Bug: 397989775
Test: Build, ui checked.
Change-Id: I872088445691078aa2ac6358254869aafb412e41
parent 6a2ef2fe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -289,6 +289,7 @@ class MediaRepositoryTest : SysuiTestCase() {
            resumeAction = resumeAction,
            isExplicit = isExplicit,
            suggestionData = mediaModel.suggestionData,
            token = session.sessionToken,
        )
    }

+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.media.remedia.data.model

import android.app.PendingIntent
import android.media.session.MediaSession
import com.android.internal.logging.InstanceId
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.media.controls.shared.model.MediaButton
@@ -71,4 +72,5 @@ data class MediaDataModel(
    val isExplicit: Boolean,
    /** Device suggestions data */
    val suggestionData: SuggestionData?,
    val token: MediaSession.Token?,
)
+2 −4
Original line number Diff line number Diff line
@@ -147,10 +147,7 @@ constructor(

                applicationScope.launch {
                    val controller =
                        if (
                            currentModel != null &&
                                activeControllers[currentModel.instanceId]?.sessionToken == token
                        ) {
                        if (currentModel != null && currentModel.token == token) {
                            activeControllers[currentModel.instanceId]
                        } else {
                            // Clear controller state if changed for the same media session.
@@ -236,6 +233,7 @@ constructor(
                resumeAction = resumeAction,
                isExplicit = isExplicit,
                suggestionData = suggestionData,
                token = token,
            )
        }
    }
+62 −8
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.systemui.media.remedia.domain.interactor

import android.app.ActivityOptions
import android.app.BroadcastOptions
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.session.MediaSession
import android.provider.Settings
import android.util.Log
import androidx.compose.ui.graphics.ImageBitmap
@@ -27,6 +30,8 @@ import com.android.internal.jank.Cuj
import com.android.internal.logging.InstanceId
import com.android.settingslib.media.LocalMediaManager.MediaDeviceState
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.biometrics.Utils.toBitmap
import com.android.systemui.common.shared.model.ContentDescription
@@ -38,6 +43,7 @@ import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
import com.android.systemui.media.controls.domain.pipeline.getNotificationActions
import com.android.systemui.media.controls.shared.model.MediaAction
import com.android.systemui.media.controls.shared.model.SuggestionData
import com.android.systemui.media.dialog.MediaOutputDialogManager
import com.android.systemui.media.remedia.data.model.MediaDataModel
import com.android.systemui.media.remedia.data.repository.MediaRepository
import com.android.systemui.media.remedia.domain.model.MediaActionModel
@@ -82,6 +88,7 @@ constructor(
    private val activityStarter: ActivityStarter,
    private val activityIntentHelper: ActivityIntentHelper,
    private val lockscreenUserManager: NotificationLockscreenUserManager,
    private val mediaOutputDialogManager: MediaOutputDialogManager,
) : MediaInteractor {

    override val sessions: List<MediaSessionModel>
@@ -161,6 +168,9 @@ constructor(
                                        contentDescription = null,
                                    ),
                            isInProgress = false,
                            onClick = { expandable ->
                                startOutputSwitcherClick(dataModel, expandable)
                            },
                        )
                    }

@@ -237,6 +247,7 @@ constructor(
            suggestedMediaDeviceData.name,
            suggestedMediaDeviceData.icon.asIcon(),
            suggestedMediaDeviceData.connectionState == MediaDeviceState.STATE_CONNECTING,
            onClick = { suggestedMediaDeviceData.connect() },
        )
    }

@@ -250,7 +261,7 @@ constructor(
    }

    private fun launchOverLockscreen(
        expandable: Expandable,
        expandable: Expandable?,
        pendingIntent: PendingIntent,
    ): Boolean {
        val showOverLockscreen =
@@ -261,6 +272,7 @@ constructor(
                )
        if (showOverLockscreen) {
            try {
                if (expandable != null) {
                    activityStarter.startPendingIntentMaybeDismissingKeyguard(
                        pendingIntent,
                        /* intentSentUiThreadCallback = */ null,
@@ -268,6 +280,13 @@ constructor(
                            Cuj.CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER
                        ),
                    )
                } else {
                    val options = BroadcastOptions.makeBasic()
                    options.isInteractive = true
                    options.pendingIntentBackgroundActivityStartMode =
                        ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS
                    pendingIntent.send(options.toBundle())
                }
            } catch (e: PendingIntent.CanceledException) {
                Log.e(TAG, "pending intent was canceled")
            }
@@ -276,6 +295,41 @@ constructor(
        return false
    }

    private fun startOutputSwitcherClick(dataModel: MediaDataModel, expandable: Expandable) {
        dataModel.outputDevice?.intent?.let { startDeviceIntent(dataModel.instanceId, it) }
            ?: startMediaOutputDialog(expandable, dataModel.packageName, dataModel.token)
    }

    private fun startMediaOutputDialog(
        expandable: Expandable,
        packageName: String,
        token: MediaSession.Token? = null,
    ) {
        mediaOutputDialogManager.createAndShowWithController(
            packageName,
            true,
            expandable.dialogController(),
            token = token,
        )
    }

    private fun Expandable.dialogController(): DialogTransitionAnimator.Controller? {
        return dialogTransitionController(
            cuj =
                DialogCuj(Cuj.CUJ_SHADE_DIALOG_OPEN, MediaOutputDialogManager.INTERACTION_JANK_TAG)
        )
    }

    private fun startDeviceIntent(instanceId: InstanceId, deviceIntent: PendingIntent) {
        if (deviceIntent.isActivity) {
            if (!launchOverLockscreen(expandable = null, deviceIntent)) {
                activityStarter.postStartActivityDismissingKeyguard(deviceIntent)
            }
        } else {
            Log.w(TAG, "Device pending intent of instanceId=$instanceId is not an activity.")
        }
    }

    companion object {
        private const val TAG = "MediaInteractor"
        private val settingsIntent: Intent = Intent(Settings.ACTION_MEDIA_CONTROLS_SETTINGS)
+7 −1
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@

package com.android.systemui.media.remedia.domain.model

import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon

data class MediaOutputDeviceModel(val name: String, val icon: Icon, val isInProgress: Boolean)
data class MediaOutputDeviceModel(
    val name: String,
    val icon: Icon,
    val isInProgress: Boolean,
    val onClick: (Expandable) -> Unit,
)
Loading