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

Commit 72b3afc1 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB][Screen Chips] Show app name in screen record stop dialog if needed.

Builds on Ia4aa6132b342127b4b9202ecd40d561c0fb882c2 to also show "You
will stop recording [app name]" for the screen record stop dialog.
ScreenRecordRepository doesn't have this information (because
RecordingController doesn't have it), so the ScreenRecordChipInteractor
now needs to also listen to MediaProjectionRepository, which *does* have
the information.

Bug: 332662551
Flag: com.android.systemui.status_bar_screen_sharing_chips
Test: Start a screen recording for a single app -> click chip -> verify
dialog says "You will stop recording [app name]", with [app name] in
bold
Test: Start a screen recording for the entire screen -> click chip ->
verify dialog says just "You will stop recording your screen"
Test: atest ScreenRecordChipInteractorTest
EndScreenRecordingDialogDelegateTest

Change-Id: Id9aa09b246dc42ebbf56fca276b336820e574823
parent 04481f29
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -323,6 +323,8 @@
    <string name="screenrecord_stop_dialog_title">Stop recording screen?</string>
    <!-- Text telling a user that they will stop recording their screen if they click the "Stop recording" button [CHAR LIMIT=100] -->
    <string name="screenrecord_stop_dialog_message">You will stop recording your screen</string>
    <!-- Text telling a user that they will stop recording the contents of the specified [app_name] if they click the "Stop recording" button. Note that the app name will appear in bold. [CHAR LIMIT=100] -->
    <string name="screenrecord_stop_dialog_message_specific_app">You will stop recording &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
    <!-- Button to stop a screen recording [CHAR LIMIT=35] -->
    <string name="screenrecord_stop_dialog_button">Stop recording</string>

+5 −1
Original line number Diff line number Diff line
@@ -49,11 +49,15 @@ constructor(
     *   specify which app is currently being projected.
     */
    fun getDialogMessage(
        state: MediaProjectionState.Projecting,
        state: MediaProjectionState,
        @StringRes genericMessageResId: Int,
        @StringRes specificAppMessageResId: Int,
    ): CharSequence {
        when (state) {
            // NotProjecting might happen if there's a bit of lag between when the screen recording
            // starts and when MediaProjection is aware that it's started, so handle it here just in
            // case.
            is MediaProjectionState.NotProjecting,
            is MediaProjectionState.Projecting.EntireScreen ->
                return context.getString(genericMessageResId)
            is MediaProjectionState.Projecting.SingleTask -> {
+20 −10
Original line number Diff line number Diff line
@@ -21,20 +21,22 @@ import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
import com.android.systemui.res.R
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor
import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor.Companion.createDialogLaunchOnClickListener
import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.chips.screenrecord.ui.view.EndScreenRecordingDialogDelegate
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

@@ -45,14 +47,20 @@ class ScreenRecordChipInteractor
constructor(
    @Application private val scope: CoroutineScope,
    private val screenRecordRepository: ScreenRecordRepository,
    private val mediaProjectionRepository: MediaProjectionRepository,
    private val systemClock: SystemClock,
    private val dialogFactory: SystemUIDialog.Factory,
    private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
    private val dialogTransitionAnimator: DialogTransitionAnimator,
) : OngoingActivityChipInteractor {
    override val chip: StateFlow<OngoingActivityChipModel> =
        screenRecordRepository.screenRecordState
            .map { state ->
                when (state) {
        // ScreenRecordRepository has the main "is the screen being recorded?" state, and
        // MediaProjectionRepository has information about what specifically is being recorded (a
        // single app or the entire screen)
        combine(
                screenRecordRepository.screenRecordState,
                mediaProjectionRepository.mediaProjectionState,
            ) { screenRecordState, mediaProjectionState ->
                when (screenRecordState) {
                    is ScreenRecordModel.DoingNothing,
                    // TODO(b/332662551): Implement the 3-2-1 countdown chip.
                    is ScreenRecordModel.Starting -> OngoingActivityChipModel.Hidden
@@ -62,7 +70,7 @@ constructor(
                            icon = Icon.Resource(ICON, contentDescription = null),
                            startTimeMs = systemClock.elapsedRealtime(),
                            createDialogLaunchOnClickListener(
                                dialogDelegate,
                                createDelegate(mediaProjectionState),
                                dialogTransitionAnimator
                            ),
                        )
@@ -75,11 +83,13 @@ constructor(
        scope.launch { screenRecordRepository.stopRecording() }
    }

    private val dialogDelegate =
        EndScreenRecordingDialogDelegate(
            dialogFactory,
    private fun createDelegate(state: MediaProjectionState): EndScreenRecordingDialogDelegate {
        return EndScreenRecordingDialogDelegate(
            endMediaProjectionDialogHelper,
            this@ScreenRecordChipInteractor,
            state,
        )
    }

    companion object {
        @DrawableRes val ICON = R.drawable.ic_screenrecord
+12 −4
Original line number Diff line number Diff line
@@ -17,26 +17,34 @@
package com.android.systemui.statusbar.chips.screenrecord.ui.view

import android.os.Bundle
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor
import com.android.systemui.statusbar.phone.SystemUIDialog

/** A dialog that lets the user stop an ongoing screen recording. */
class EndScreenRecordingDialogDelegate(
    private val systemUIDialogFactory: SystemUIDialog.Factory,
    private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
    private val interactor: ScreenRecordChipInteractor,
    private val state: MediaProjectionState,
) : SystemUIDialog.Delegate {

    override fun createDialog(): SystemUIDialog {
        return systemUIDialogFactory.create(this)
        return endMediaProjectionDialogHelper.createDialog(this)
    }

    override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
        with(dialog) {
            setIcon(ScreenRecordChipInteractor.ICON)
            setTitle(R.string.screenrecord_stop_dialog_title)
            // TODO(b/332662551): Use a different message if they're sharing just a single app.
            setMessage(R.string.screenrecord_stop_dialog_message)
            setMessage(
                endMediaProjectionDialogHelper.getDialogMessage(
                    state,
                    genericMessageResId = R.string.screenrecord_stop_dialog_message,
                    specificAppMessageResId = R.string.screenrecord_stop_dialog_message_specific_app
                )
            )
            // 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)
+12 −0
Original line number Diff line number Diff line
@@ -55,6 +55,18 @@ class EndMediaProjectionDialogHelperTest : SysuiTestCase() {
        verify(kosmos.mockSystemUIDialogFactory).create(delegate)
    }

    @Test
    fun getDialogMessage_notProjecting_isGenericMessage() {
        val result =
            underTest.getDialogMessage(
                MediaProjectionState.NotProjecting,
                R.string.accessibility_home,
                R.string.cast_to_other_device_stop_dialog_message_specific_app,
            )

        assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
    }

    @Test
    fun getDialogMessage_entireScreen_isGenericMessage() {
        val result =
Loading