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

Commit 0014623f authored by Alejandro Nijamkin's avatar Alejandro Nijamkin Committed by Ale Nijamkin
Browse files

[flexiglass] Conditions handleShadeTouchability to run conditionally

handleShadeTouchability is responsible for the attached bug because it
sometimes emits a false right when we unlock the device, causing the
system to switch to the Lockscreen scene while needing to actually
unlock.

The power button putting the device to sleep is handled by a different
coroutine in SceneContainerStartable so that's still covered.

Fix: 395728344
Test: current tests pass
Test: manually attempted to reproduce the bug about 20 times without
success
Flag: com.android.systemui.scene_container

Change-Id: I5becb58e6b9a23a2a9f7ea6522ca12f4557c5d12
parent 01694b7b
Loading
Loading
Loading
Loading
+1 −14
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.scene.domain.resolver

import android.util.Log
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -84,7 +83,7 @@ constructor(
        isDreamingWithOverlay: Boolean,
        isAbleToDream: Boolean,
    ): SceneKey {
        val result = when {
        return when {
            // Dream can run even if Keyguard is disabled, thus it has the highest priority here.
            isDreamingWithOverlay && isAbleToDream -> Scenes.Dream
            !isKeyguardEnabled -> Scenes.Gone
@@ -93,21 +92,9 @@ constructor(
            !isUnlocked -> Scenes.Lockscreen
            else -> Scenes.Gone
        }
        Log.d(TAG, "homeScene emitting $result, values:")
        Log.d(TAG, "  isKeyguardEnabled=$isKeyguardEnabled")
        Log.d(TAG, "  canSwipeToEnter=$canSwipeToEnter")
        Log.d(TAG, "  isDeviceEntered=$isDeviceEntered" )
        Log.d(TAG, "  isUnlocked=$isUnlocked")
        Log.d(TAG, "  isDreamingWithOverlay=$isDreamingWithOverlay")
        Log.d(TAG, "  isAbleToDream=$isAbleToDream")
        Log.d(TAG, "")
        return result
    }

    companion object {

        private const val TAG = "HomeSceneFamilyResolver"

        val homeScenes =
            setOf(
                Scenes.Gone,
+26 −8
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
@@ -610,17 +611,26 @@ constructor(

    private fun handleShadeTouchability() {
        applicationScope.launch {
            repeatWhen(deviceEntryInteractor.isDeviceEntered.map { !it }) {
                // Run logic only when the device isn't entered.
                repeatWhen(
                    sceneInteractor.transitionState.map { !it.isTransitioning(to = Scenes.Gone) }
                ) {
                    // Run logic only when not transitioning to gone.
                    shadeInteractor.isShadeTouchable
                        .distinctUntilChanged()
                        .filter { !it }
                        .collect {
                            switchToScene(
                                targetSceneKey = Scenes.Lockscreen,
                        loggingReason = "device became non-interactive (SceneContainerStartable)",
                                loggingReason =
                                    "device became non-interactive (SceneContainerStartable)",
                            )
                        }
                }
            }
        }
    }

    private fun handleDisableFlags() {
        applicationScope.launch {
@@ -1013,6 +1023,14 @@ constructor(
        }
    }

    private suspend fun repeatWhen(condition: Flow<Boolean>, block: suspend () -> Unit) {
        condition.distinctUntilChanged().collectLatest { conditionMet ->
            if (conditionMet) {
                block()
            }
        }
    }

    companion object {
        private const val TAG = "SceneContainerStartable"
    }
+10 −26
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.shade.domain.interactor

import android.util.Log
import com.android.app.tracing.coroutines.flow.flowName
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -39,7 +38,6 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn

/** The non-empty [ShadeInteractor] implementation. */
@@ -100,31 +98,17 @@ constructor(

    override val isShadeTouchable: Flow<Boolean> =
        combine(
            powerInteractor.isAsleep.onEach {
                Log.d(TAG, "isShadeTouchable: upstream isAsleep=$it")
            },
            keyguardTransitionInteractor
                .isInTransition(Edge.create(to = KeyguardState.AOD))
                .onEach { Log.d(TAG, "isShadeTouchable: upstream isTransitioningToAod=$it") },
            keyguardRepository.dozeTransitionModel
                .map { it.to == DozeStateModel.DOZE_PULSING }
                .onEach { Log.d(TAG, "isShadeTouchable: upstream isPulsing=$it") },
            powerInteractor.isAsleep,
            keyguardTransitionInteractor.isInTransition(Edge.create(to = KeyguardState.AOD)),
            keyguardRepository.dozeTransitionModel.map { it.to == DozeStateModel.DOZE_PULSING },
        ) { isAsleep, isTransitioningToAod, isPulsing ->
            val downstream =
            when {
                    // If the device is transitioning to AOD, only accept touches if
                    // still animating.
                // If the device is transitioning to AOD, only accept touches if still animating.
                isTransitioningToAod -> dozeParams.shouldControlScreenOff()
                // If the device is asleep, only accept touches if there's a pulse
                isAsleep -> isPulsing
                else -> true
            }
            Log.d(TAG, "isShadeTouchable emitting $downstream, values:")
            Log.d(TAG, "  isAsleep=$isAsleep")
            Log.d(TAG, "  isTransitioningToAod=$isTransitioningToAod")
            Log.d(TAG, "  isPulsing=$isPulsing")
            Log.d(TAG, "")
            downstream
        }

    override val isExpandToQsEnabled: Flow<Boolean> =