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

Commit 4e27a972 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov Committed by Android (Google) Code Review
Browse files

Merge changes I4ea03743,I84993c71 into main

* changes:
  [SB][Screen Chips] Immediately hide chip after stopping via dialog.
  [SB][Screen Chips] Re-add animation from chip -> stop dialog, and CUJs.
parents 4e81ba44 4b095d86
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ constructor(
        interactor.ongoingCallState
            .map { state ->
                when (state) {
                    is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden
                    is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden()
                    is OngoingCallModel.InCall -> {
                        // This block mimics OngoingCallController#updateChip.
                        if (state.startTimeMs <= 0L) {
@@ -82,7 +82,7 @@ constructor(
                    }
                }
            }
            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden())

    private fun getOnClickListener(state: OngoingCallModel.InCall): View.OnClickListener? {
        if (state.intent == null) {
+4 −3
Original line number Diff line number Diff line
@@ -44,9 +44,10 @@ class EndCastScreenToOtherDeviceDialogDelegate(
            // No custom on-click, because the dialog will automatically be dismissed when the
            // button is clicked anyway.
            setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
            setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
                stopAction.invoke()
            }
            setPositiveButton(
                R.string.cast_to_other_device_stop_dialog_button,
                endMediaProjectionDialogHelper.wrapStopAction(stopAction),
            )
        }
    }

+4 −3
Original line number Diff line number Diff line
@@ -55,9 +55,10 @@ class EndGenericCastToOtherDeviceDialogDelegate(
            // No custom on-click, because the dialog will automatically be dismissed when the
            // button is clicked anyway.
            setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
            setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
                stopAction.invoke()
            }
            setPositiveButton(
                R.string.cast_to_other_device_stop_dialog_button,
                endMediaProjectionDialogHelper.wrapStopAction(stopAction),
            )
        }
    }
}
+33 −14
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel

import android.content.Context
import androidx.annotation.DrawableRes
import com.android.internal.jank.Cuj
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
@@ -35,6 +38,7 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.model.Project
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.ChipTransitionHelper
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
import com.android.systemui.util.time.SystemClock
@@ -60,6 +64,7 @@ constructor(
    private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
    private val mediaRouterChipInteractor: MediaRouterChipInteractor,
    private val systemClock: SystemClock,
    private val dialogTransitionAnimator: DialogTransitionAnimator,
    private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
    @StatusBarChipsLog private val logger: LogBuffer,
) : OngoingActivityChipViewModel {
@@ -74,18 +79,18 @@ constructor(
        mediaProjectionChipInteractor.projection
            .map { projectionModel ->
                when (projectionModel) {
                    is ProjectionChipModel.NotProjecting -> OngoingActivityChipModel.Hidden
                    is ProjectionChipModel.NotProjecting -> OngoingActivityChipModel.Hidden()
                    is ProjectionChipModel.Projecting -> {
                        if (projectionModel.type != ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE) {
                            OngoingActivityChipModel.Hidden
                            OngoingActivityChipModel.Hidden()
                        } else {
                            createCastScreenToOtherDeviceChip(projectionModel)
                        }
                    }
                }
            }
            // See b/347726238.
            .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
            // See b/347726238 for [SharingStarted.Lazily] reasoning.
            .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden())

    /**
     * The cast chip to show, based only on MediaRouter API events.
@@ -109,7 +114,7 @@ constructor(
        mediaRouterChipInteractor.mediaRouterCastingState
            .map { routerModel ->
                when (routerModel) {
                    is MediaRouterCastModel.DoingNothing -> OngoingActivityChipModel.Hidden
                    is MediaRouterCastModel.DoingNothing -> OngoingActivityChipModel.Hidden()
                    is MediaRouterCastModel.Casting -> {
                        // A consequence of b/269975671 is that MediaRouter will mark a device as
                        // casting before casting has actually started. To alleviate this bug a bit,
@@ -123,9 +128,9 @@ constructor(
                    }
                }
            }
            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden())

    override val chip: StateFlow<OngoingActivityChipModel> =
    private val internalChip: StateFlow<OngoingActivityChipModel> =
        combine(projectionChip, routerChip) { projection, router ->
                logger.log(
                    TAG,
@@ -159,17 +164,24 @@ constructor(
                    router
                }
            }
            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden())

    private val hideChipDuringDialogTransitionHelper = ChipTransitionHelper(scope)

    override val chip: StateFlow<OngoingActivityChipModel> =
        hideChipDuringDialogTransitionHelper.createChipFlow(internalChip)

    /** Stops the currently active projection. */
    private fun stopProjecting() {
        logger.log(TAG, LogLevel.INFO, {}, { "Stop casting requested (projection)" })
    private fun stopProjectingFromDialog() {
        logger.log(TAG, LogLevel.INFO, {}, { "Stop casting requested from dialog (projection)" })
        hideChipDuringDialogTransitionHelper.onActivityStoppedFromDialog()
        mediaProjectionChipInteractor.stopProjecting()
    }

    /** Stops the currently active media route. */
    private fun stopMediaRouterCasting() {
        logger.log(TAG, LogLevel.INFO, {}, { "Stop casting requested (router)" })
    private fun stopMediaRouterCastingFromDialog() {
        logger.log(TAG, LogLevel.INFO, {}, { "Stop casting requested from dialog (router)" })
        hideChipDuringDialogTransitionHelper.onActivityStoppedFromDialog()
        mediaRouterChipInteractor.stopCasting()
    }

@@ -190,6 +202,8 @@ constructor(
            startTimeMs = systemClock.elapsedRealtime(),
            createDialogLaunchOnClickListener(
                createCastScreenToOtherDeviceDialogDelegate(state),
                dialogTransitionAnimator,
                DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Cast to other device"),
                logger,
                TAG,
            ),
@@ -207,6 +221,11 @@ constructor(
            colors = ColorsModel.Red,
            createDialogLaunchOnClickListener(
                createGenericCastToOtherDeviceDialogDelegate(deviceName),
                dialogTransitionAnimator,
                DialogCuj(
                    Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP,
                    tag = "Cast to other device audio only",
                ),
                logger,
                TAG,
            ),
@@ -219,7 +238,7 @@ constructor(
        EndCastScreenToOtherDeviceDialogDelegate(
            endMediaProjectionDialogHelper,
            context,
            stopAction = this::stopProjecting,
            stopAction = this::stopProjectingFromDialog,
            state,
        )

@@ -228,7 +247,7 @@ constructor(
            endMediaProjectionDialogHelper,
            context,
            deviceName,
            stopAction = this::stopMediaRouterCasting,
            stopAction = this::stopMediaRouterCastingFromDialog,
        )

    companion object {
+25 −0
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@
package com.android.systemui.statusbar.chips.mediaprojection.ui.view

import android.app.ActivityManager
import android.content.DialogInterface
import android.content.pm.PackageManager
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -29,6 +31,7 @@ class EndMediaProjectionDialogHelper
@Inject
constructor(
    private val dialogFactory: SystemUIDialog.Factory,
    private val dialogTransitionAnimator: DialogTransitionAnimator,
    private val packageManager: PackageManager,
) {
    /** Creates a new [SystemUIDialog] using the given delegate. */
@@ -36,6 +39,28 @@ constructor(
        return dialogFactory.create(delegate)
    }

    /**
     * Returns the click listener that should be invoked if a user clicks "Stop" on the end media
     * projection dialog.
     *
     * The click listener will invoke [stopAction] and also do some UI manipulation.
     *
     * @param stopAction an action that, when invoked, should notify system API(s) that the media
     *   projection should be stopped.
     */
    fun wrapStopAction(stopAction: () -> Unit): DialogInterface.OnClickListener {
        return DialogInterface.OnClickListener { _, _ ->
            // If the projection is stopped, then the chip will disappear, so we don't want the
            // dialog to animate back into the chip just for the chip to disappear in a few frames.
            dialogTransitionAnimator.disableAllCurrentDialogsExitAnimations()
            stopAction.invoke()
            // TODO(b/332662551): If the projection is stopped, there's a brief moment where the
            // dialog closes and the chip re-shows because the system APIs haven't come back and
            // told SysUI that the projection has officially stopped. It would be great for the chip
            // to not re-show at all.
        }
    }

    fun getAppName(state: MediaProjectionState.Projecting): CharSequence? {
        val specificTaskInfo =
            if (state is MediaProjectionState.Projecting.SingleTask) {
Loading