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

Commit 04b421bc authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge "Ensure RDM dialog is shown after screen off/on" into main

parents 9dd1b5f0 f4bf234d
Loading
Loading
Loading
Loading
+47 −20
Original line number Original line Diff line number Diff line
@@ -20,6 +20,8 @@ import android.content.Context
import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.feature.flags.Flags
import android.hardware.devicestate.feature.flags.Flags
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.CoreStartable
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Application
@@ -28,8 +30,11 @@ import com.android.systemui.statusbar.phone.SystemUIDialog
import javax.inject.Inject
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch


/**
/**
 * Provides a {@link com.android.systemui.statusbar.phone.SystemUIDialog} to be shown on the inner
 * Provides a {@link com.android.systemui.statusbar.phone.SystemUIDialog} to be shown on the inner
@@ -46,6 +51,7 @@ internal constructor(
    private val rearDisplayStateInteractor: RearDisplayStateInteractor,
    private val rearDisplayStateInteractor: RearDisplayStateInteractor,
    private val rearDisplayInnerDialogDelegateFactory: RearDisplayInnerDialogDelegate.Factory,
    private val rearDisplayInnerDialogDelegateFactory: RearDisplayInnerDialogDelegate.Factory,
    @Application private val scope: CoroutineScope,
    @Application private val scope: CoroutineScope,
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
) : CoreStartable, AutoCloseable {
) : CoreStartable, AutoCloseable {


    companion object {
    companion object {
@@ -53,6 +59,16 @@ internal constructor(
    }
    }


    @VisibleForTesting var stateChangeListener: Job? = null
    @VisibleForTesting var stateChangeListener: Job? = null
    private val keyguardVisible = MutableStateFlow(false)
    private val keyguardVisibleFlow = keyguardVisible.asStateFlow()

    @VisibleForTesting
    val keyguardCallback =
        object : KeyguardUpdateMonitorCallback() {
            override fun onKeyguardVisibilityChanged(visible: Boolean) {
                keyguardVisible.value = visible
            }
        }


    override fun close() {
    override fun close() {
        stateChangeListener?.cancel()
        stateChangeListener?.cancel()
@@ -62,13 +78,23 @@ internal constructor(
        if (Flags.deviceStateRdmV2()) {
        if (Flags.deviceStateRdmV2()) {
            var dialog: SystemUIDialog? = null
            var dialog: SystemUIDialog? = null


            keyguardUpdateMonitor.registerCallback(keyguardCallback)

            stateChangeListener =
            stateChangeListener =
                rearDisplayStateInteractor.state
                scope.launch {
                    .map {
                    combine(rearDisplayStateInteractor.state, keyguardVisibleFlow) {
                        when (it) {
                            rearDisplayState,
                            keyguardVisible ->
                            Pair(rearDisplayState, keyguardVisible)
                        }
                        .collectLatest { (rearDisplayState, keyguardVisible) ->
                            when (rearDisplayState) {
                                is RearDisplayStateInteractor.State.Enabled -> {
                                is RearDisplayStateInteractor.State.Enabled -> {
                                    if (!keyguardVisible) {
                                        val rearDisplayContext =
                                        val rearDisplayContext =
                                    context.createDisplayContext(it.innerDisplay)
                                            context.createDisplayContext(
                                                rearDisplayState.innerDisplay
                                            )
                                        val delegate =
                                        val delegate =
                                            rearDisplayInnerDialogDelegateFactory.create(
                                            rearDisplayInnerDialogDelegateFactory.create(
                                                rearDisplayContext,
                                                rearDisplayContext,
@@ -76,6 +102,7 @@ internal constructor(
                                            )
                                            )
                                        dialog = delegate.createDialog().apply { show() }
                                        dialog = delegate.createDialog().apply { show() }
                                    }
                                    }
                                }


                                is RearDisplayStateInteractor.State.Disabled -> {
                                is RearDisplayStateInteractor.State.Disabled -> {
                                    dialog?.dismiss()
                                    dialog?.dismiss()
@@ -83,7 +110,7 @@ internal constructor(
                                }
                                }
                            }
                            }
                        }
                        }
                    .launchIn(scope)
                }
        }
        }
    }
    }
}
}
+23 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.EnableFlags
import android.view.Display
import android.view.Display
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.deviceStateManager
import com.android.systemui.deviceStateManager
import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor
import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor
@@ -37,6 +38,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableSharedFlow
import org.junit.Before
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.mockito.Mockito.times
import org.mockito.kotlin.any
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.never
@@ -59,6 +61,7 @@ class RearDisplayCoreStartableTest : SysuiTestCase() {
            fakeRearDisplayStateInteractor,
            fakeRearDisplayStateInteractor,
            kosmos.rearDisplayInnerDialogDelegateFactory,
            kosmos.rearDisplayInnerDialogDelegateFactory,
            kosmos.testScope,
            kosmos.testScope,
            kosmos.keyguardUpdateMonitor,
        )
        )


    @Before
    @Before
@@ -96,6 +99,26 @@ class RearDisplayCoreStartableTest : SysuiTestCase() {
            }
            }
        }
        }


    @Test
    @EnableFlags(FLAG_DEVICE_STATE_RDM_V2)
    fun testDialogResumesAfterKeyguardGone() =
        kosmos.runTest {
            impl.use {
                it.start()
                fakeRearDisplayStateInteractor.emitRearDisplay()

                verify(mockDialog).show()

                it.keyguardCallback.onKeyguardVisibilityChanged(true)
                // Do not need to check that the dialog is dismissed, since SystemUIDialog
                // implementation handles that. We just toggle keyguard here so that the flow
                // emits.

                it.keyguardCallback.onKeyguardVisibilityChanged(false)
                verify(mockDialog, times(2)).show()
            }
        }

    private class FakeRearDisplayStateInteractor(private val kosmos: Kosmos) :
    private class FakeRearDisplayStateInteractor(private val kosmos: Kosmos) :
        RearDisplayStateInteractor {
        RearDisplayStateInteractor {
        private val stateFlow = MutableSharedFlow<RearDisplayStateInteractor.State>()
        private val stateFlow = MutableSharedFlow<RearDisplayStateInteractor.State>()