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

Commit 1834a6bd authored by Aaron Liu's avatar Aaron Liu
Browse files

Do not separate flow into two.

In the logs of the bug report, bouncershow(true) and bouncershow(hide)
is called 50 ms apart. The theory is that the ordering of the flow
collection is not deterministic because bouncershow is separated into
two separate flows with a map.

Also added a log in the bouncer repository when the bouncer is
showing/hiding.

Fixes: 274608304
Test: Open and close bouncer from occluded state.
Change-Id: I57595b76af9385bb83ab007f25347a5566e9903a
parent bb208e41
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.data.repository
package com.android.systemui.keyguard.data.repository


import android.os.Build
import android.os.Build
import android.util.Log
import com.android.keyguard.ViewMediatorCallback
import com.android.keyguard.ViewMediatorCallback
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
@@ -34,6 +35,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach


/**
/**
 * Encapsulates app state for the lock screen primary and alternate bouncer.
 * Encapsulates app state for the lock screen primary and alternate bouncer.
@@ -231,6 +233,7 @@ constructor(


        primaryBouncerShow
        primaryBouncerShow
            .logDiffsForTable(buffer, "", "PrimaryBouncerShow", false)
            .logDiffsForTable(buffer, "", "PrimaryBouncerShow", false)
            .onEach { Log.d(TAG, "Keyguard Bouncer is ${if (it) "showing" else "hiding."}") }
            .launchIn(applicationScope)
            .launchIn(applicationScope)
        primaryBouncerShowingSoon
        primaryBouncerShowingSoon
            .logDiffsForTable(buffer, "", "PrimaryBouncerShowingSoon", false)
            .logDiffsForTable(buffer, "", "PrimaryBouncerShowingSoon", false)
@@ -274,5 +277,6 @@ constructor(


    companion object {
    companion object {
        private const val NOT_VISIBLE = -1L
        private const val NOT_VISIBLE = -1L
        private const val TAG = "KeyguardBouncerRepositoryImpl"
    }
    }
}
}
+1 −2
Original line number Original line Diff line number Diff line
@@ -95,8 +95,7 @@ constructor(
    }
    }


    val keyguardAuthenticated: Flow<Boolean> = repository.keyguardAuthenticated.filterNotNull()
    val keyguardAuthenticated: Flow<Boolean> = repository.keyguardAuthenticated.filterNotNull()
    val show: Flow<Unit> = repository.primaryBouncerShow.filter { it }.map {}
    val isShowing: Flow<Boolean> = repository.primaryBouncerShow
    val hide: Flow<Unit> = repository.primaryBouncerShow.filter { !it }.map {}
    val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {}
    val startingToHide: Flow<Unit> = repository.primaryBouncerStartingToHide.filter { it }.map {}
    val isBackButtonEnabled: Flow<Boolean> = repository.isBackButtonEnabled.filterNotNull()
    val isBackButtonEnabled: Flow<Boolean> = repository.isBackButtonEnabled.filterNotNull()
    val showMessage: Flow<BouncerShowMessageModel> = repository.showMessage.filterNotNull()
    val showMessage: Flow<BouncerShowMessageModel> = repository.showMessage.filterNotNull()
+22 −22
Original line number Original line Diff line number Diff line
@@ -109,7 +109,8 @@ object KeyguardBouncerViewBinder {
                try {
                try {
                    viewModel.setBouncerViewDelegate(delegate)
                    viewModel.setBouncerViewDelegate(delegate)
                    launch {
                    launch {
                        viewModel.show.collect {
                        viewModel.isShowing.collect { isShowing ->
                            if (isShowing) {
                                // Reset Security Container entirely.
                                // Reset Security Container entirely.
                                securityContainerController.reinflateViewFlipper {
                                securityContainerController.reinflateViewFlipper {
                                    // Reset Security Container entirely.
                                    // Reset Security Container entirely.
@@ -121,13 +122,11 @@ object KeyguardBouncerViewBinder {
                                        /* turningOff= */ false
                                        /* turningOff= */ false
                                    )
                                    )
                                    securityContainerController.appear()
                                    securityContainerController.appear()
                                securityContainerController.onResume(KeyguardSecurityView.SCREEN_ON)
                                    securityContainerController.onResume(
                            }
                                        KeyguardSecurityView.SCREEN_ON
                        }
                                    )
                                }
                                }

                            } else {
                    launch {
                        viewModel.hide.collect {
                                view.visibility = View.INVISIBLE
                                view.visibility = View.INVISIBLE
                                securityContainerController.onBouncerVisibilityChanged(
                                securityContainerController.onBouncerVisibilityChanged(
                                    /* isVisible= */ false
                                    /* isVisible= */ false
@@ -137,6 +136,7 @@ object KeyguardBouncerViewBinder {
                                securityContainerController.onPause()
                                securityContainerController.onPause()
                            }
                            }
                        }
                        }
                    }


                    launch {
                    launch {
                        viewModel.startingToHide.collect {
                        viewModel.startingToHide.collect {
+4 −7
Original line number Original line Diff line number Diff line
@@ -40,11 +40,8 @@ constructor(
    /** Can the user interact with the view? */
    /** Can the user interact with the view? */
    val isInteractable: Flow<Boolean> = interactor.isInteractable
    val isInteractable: Flow<Boolean> = interactor.isInteractable


    /** Observe whether bouncer is showing. */
    /** Observe whether bouncer is showing or not. */
    val show: Flow<Unit> = interactor.show
    val isShowing: Flow<Boolean> = interactor.isShowing

    /** Observe whether bouncer is hiding. */
    val hide: Flow<Unit> = interactor.hide


    /** Observe whether bouncer is starting to hide. */
    /** Observe whether bouncer is starting to hide. */
    val startingToHide: Flow<Unit> = interactor.startingToHide
    val startingToHide: Flow<Unit> = interactor.startingToHide
@@ -70,8 +67,8 @@ constructor(
    /** Observe whether we should update fps is showing. */
    /** Observe whether we should update fps is showing. */
    val shouldUpdateSideFps: Flow<Unit> =
    val shouldUpdateSideFps: Flow<Unit> =
        merge(
        merge(
            interactor.hide,
            interactor.isShowing.map {},
            interactor.show,
            interactor.startingToHide,
            interactor.startingDisappearAnimation.filterNotNull().map {}
            interactor.startingDisappearAnimation.filterNotNull().map {}
        )
        )


+22 −0
Original line number Original line Diff line number Diff line
@@ -125,4 +125,26 @@ class KeyguardBouncerViewModelTest : SysuiTestCase() {
        assertThat(sideFpsIsShowing).isEqualTo(true)
        assertThat(sideFpsIsShowing).isEqualTo(true)
        job.cancel()
        job.cancel()
    }
    }

    @Test
    fun isShowing() = runTest {
        var isShowing: Boolean? = null
        val job = underTest.isShowing.onEach { isShowing = it }.launchIn(this)
        repository.setPrimaryShow(true)
        // Run the tasks that are pending at this point of virtual time.
        runCurrent()
        assertThat(isShowing).isEqualTo(true)
        job.cancel()
    }

    @Test
    fun isNotShowing() = runTest {
        var isShowing: Boolean? = null
        val job = underTest.isShowing.onEach { isShowing = it }.launchIn(this)
        repository.setPrimaryShow(false)
        // Run the tasks that are pending at this point of virtual time.
        runCurrent()
        assertThat(isShowing).isEqualTo(false)
        job.cancel()
    }
}
}