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

Commit 5e3b033c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "ActionButtonModel refactor" into main

parents bd88cf43 9838809d
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
@@ -639,7 +640,7 @@ private fun ActionArea(viewModel: BouncerSceneContentViewModel, modifier: Modifi
    val appearMoveAnimatable = remember { Animatable(0f) }
    val appearAnimationInitialOffset = with(LocalDensity.current) { 80.dp.toPx() }

    actionButton?.let { actionButtonViewModel ->
    actionButton?.let { actionButtonModel ->
        LaunchedEffect(Unit) {
            appearFadeInAnimatable.animateTo(
                targetValue = 1f,
@@ -678,12 +679,14 @@ private fun ActionArea(viewModel: BouncerSceneContentViewModel, modifier: Modifi
                    .background(color = MaterialTheme.colorScheme.tertiaryContainer)
                    .semantics { role = Role.Button }
                    .combinedClickable(
                        onClick = { actionButtonViewModel.onClick() },
                        onLongClick = actionButtonViewModel.onLongClick?.let { { it.invoke() } },
                        onClick = { actionButton?.let { viewModel.onActionButtonClicked(it) } },
                        onLongClick = {
                            actionButton?.let { viewModel.onActionButtonLongClicked(it) }
                        },
                    )
        ) {
            Text(
                text = actionButtonViewModel.label,
                text = stringResource(id = actionButtonModel.labelResId),
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onTertiaryContainer,
                modifier = Modifier.align(Alignment.Center).padding(ButtonDefaults.ContentPadding),
+15 −14
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.internal.util.emergencyAffordanceManager
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
@@ -83,7 +84,7 @@ class BouncerActionButtonInteractorTest : SysuiTestCase() {
        overrideResource(R.string.lockscreen_return_to_call, MESSAGE_RETURN_TO_CALL)
        overrideResource(
            R.bool.config_enable_emergency_call_while_sim_locked,
            ENABLE_EMERGENCY_CALL_WHILE_SIM_LOCKED
            ENABLE_EMERGENCY_CALL_WHILE_SIM_LOCKED,
        )
        whenever(selectedUserInteractor.getSelectedUserId()).thenReturn(currentUserId)
        whenever(emergencyAffordanceManager.needsEmergencyAffordance())
@@ -123,11 +124,11 @@ class BouncerActionButtonInteractorTest : SysuiTestCase() {
            kosmos.fakeTelephonyRepository.setIsInCall(true)

            assertThat(actionButton).isNotNull()
            assertThat(actionButton?.label).isEqualTo(MESSAGE_RETURN_TO_CALL)
            assertThat(actionButton?.onClick).isNotNull()
            assertThat(actionButton?.onLongClick).isNull()
            assertThat(actionButton?.labelResId).isEqualTo(R.string.lockscreen_return_to_call)
            assertThat(actionButton)
                .isInstanceOf(BouncerActionButtonModel.ReturnToCallButtonModel::class.java)

            actionButton?.onClick?.invoke()
            underTest.onReturnToCallButtonClicked()
            runCurrent()

            assertThat(metricsLogger.logs.size).isEqualTo(1)
@@ -150,11 +151,11 @@ class BouncerActionButtonInteractorTest : SysuiTestCase() {
            kosmos.fakeTelephonyRepository.setIsInCall(false)

            assertThat(actionButton).isNotNull()
            assertThat(actionButton?.label).isEqualTo(MESSAGE_EMERGENCY_CALL)
            assertThat(actionButton?.onClick).isNotNull()
            assertThat(actionButton?.onLongClick).isNotNull()
            assertThat(actionButton?.labelResId).isEqualTo(R.string.lockscreen_emergency_call)
            assertThat(actionButton)
                .isInstanceOf(BouncerActionButtonModel.EmergencyButtonModel::class.java)

            actionButton?.onClick?.invoke()
            underTest.onEmergencyButtonClicked()
            runCurrent()

            assertThat(metricsLogger.logs.size).isEqualTo(1)
@@ -167,12 +168,12 @@ class BouncerActionButtonInteractorTest : SysuiTestCase() {
            //  ActivityStarter interface here.
            verify(emergencyAffordanceManager, never()).performEmergencyCall()

            actionButton?.onLongClick?.invoke()
            underTest.onEmergencyButtonLongClicked()
            verify(emergencyAffordanceManager).performEmergencyCall()
        }

    @Test
    fun noCall_insecureAuthMethodButSecureSim_emergencyCallButton() =
    fun noCall_insecureAuthMethodButSecureSim_emergencyCallButtonIsActionButton() =
        testScope.runTest {
            val underTest = kosmos.bouncerActionButtonInteractor
            val actionButton by collectLastValue(underTest.actionButton)
@@ -184,9 +185,9 @@ class BouncerActionButtonInteractorTest : SysuiTestCase() {
            runCurrent()

            assertThat(actionButton).isNotNull()
            assertThat(actionButton?.label).isEqualTo(MESSAGE_EMERGENCY_CALL)
            assertThat(actionButton?.onClick).isNotNull()
            assertThat(actionButton?.onLongClick).isNotNull()
            assertThat(actionButton?.labelResId).isEqualTo(R.string.lockscreen_emergency_call)
            assertThat(actionButton)
                .isInstanceOf(BouncerActionButtonModel.EmergencyButtonModel::class.java)
        }

    @Test
+2 −2
Original line number Diff line number Diff line
@@ -332,7 +332,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
            assertWithMessage("Bouncer action button not visible")
                .that(bouncerActionButton)
                .isNotNull()
            bouncerActionButton?.onClick?.invoke()
            kosmos.bouncerSceneContentViewModel.onActionButtonClicked(bouncerActionButton!!)
            runCurrent()

            // TODO(b/369765704): Assert that an activity was started once we use ActivityStarter.
@@ -354,7 +354,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
            assertWithMessage("Bouncer action button not visible during call")
                .that(bouncerActionButton)
                .isNotNull()
            bouncerActionButton?.onClick?.invoke()
            kosmos.bouncerSceneContentViewModel.onActionButtonClicked(bouncerActionButton!!)
            runCurrent()

            verify(kosmos.mockTelecomManager).showInCallScreen(any())
+24 −31
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import com.android.internal.util.EmergencyAffordanceManager
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.bouncer.data.repository.EmergencyServicesRepository
import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel
import com.android.systemui.bouncer.ui.helper.BouncerHapticPlayer
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
@@ -75,7 +74,6 @@ constructor(
    private val metricsLogger: MetricsLogger,
    private val dozeLogger: DozeLogger,
    private val sceneInteractor: Lazy<SceneInteractor>,
    private val bouncerHapticPlayer: BouncerHapticPlayer,
) {
    /** The bouncer action button. If `null`, the button should not be shown. */
    val actionButton: Flow<BouncerActionButtonModel?> =
@@ -90,43 +88,38 @@ constructor(
                )
                .map {
                    when {
                        isReturnToCallButton() -> returnToCallButtonModel
                        isEmergencyCallButton() -> emergencyCallButtonModel
                        isReturnToCallButton() ->
                            BouncerActionButtonModel.ReturnToCallButtonModel(
                                labelResourceId = R.string.lockscreen_return_to_call
                            )
                        isEmergencyCallButton() ->
                            BouncerActionButtonModel.EmergencyButtonModel(
                                labelResourceId = R.string.lockscreen_emergency_call
                            )
                        else -> null // Do not show the button.
                    }
                }
                .distinctUntilChanged()
        }

    private val returnToCallButtonModel: BouncerActionButtonModel by lazy {
        BouncerActionButtonModel(
            label = applicationContext.getString(R.string.lockscreen_return_to_call),
            onClick = {
    fun onReturnToCallButtonClicked() {
        prepareToPerformAction()
        returnToCall()
            },
            onLongClick = null,
        )
    }

    private val emergencyCallButtonModel: BouncerActionButtonModel by lazy {
        BouncerActionButtonModel(
            label = applicationContext.getString(R.string.lockscreen_emergency_call),
            onClick = {
                // TODO(b/373930432): haptics should be played at the UI layer -> refactor
                bouncerHapticPlayer.playEmergencyButtonClickFeedback()
    fun onEmergencyButtonClicked() {
        prepareToPerformAction()
        dozeLogger.logEmergencyCall()
        startEmergencyDialerActivity()
            },
            // TODO(b/369767936): The long click detector doesn't work properly, investigate.
            onLongClick = {
    }

    fun onEmergencyButtonLongClicked() {
        if (emergencyAffordanceManager.needsEmergencyAffordance()) {
            prepareToPerformAction()

            // TODO(b/369767936): Check that !longPressWasDragged before invoking.
            emergencyAffordanceManager.performEmergencyCall()
        }
            },
        )
    }

    private fun startEmergencyDialerActivity() {
+11 −12
Original line number Diff line number Diff line
@@ -16,17 +16,16 @@

package com.android.systemui.bouncer.shared.model

/** Models the action button on the bouncer. */
data class BouncerActionButtonModel(
    /** The text to be shown on the button. */
    val label: String,
import androidx.annotation.StringRes

    /** The action to perform when the user clicks on the button. */
    val onClick: () -> Unit,
/** Models the action button on the bouncer. */
sealed class BouncerActionButtonModel(
    /** The resource Id of the text to be shown on the button. */
    @StringRes val labelResId: Int
) {
    data class EmergencyButtonModel(@StringRes private val labelResourceId: Int) :
        BouncerActionButtonModel(labelResourceId)

    /**
     * The action to perform when the user long-clicks on the button. When not provided, long-clicks
     * will be treated as regular clicks.
     */
    val onLongClick: (() -> Unit)? = null,
)
    data class ReturnToCallButtonModel(@StringRes private val labelResourceId: Int) :
        BouncerActionButtonModel(labelResourceId)
}
Loading