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

Commit d6ae48ea authored by Matt Pietal's avatar Matt Pietal
Browse files

Transitions - Add occlusion state

Add specific OCCLUDED state, and manage transitions between states.

Refactor all transition interactors to focus around the From starting
states.

Add dream overlay-specific callback, in addition to dreaming
information, as the overlay can control exactly when the dream exits.

Test: atest KeyguardRepositoryImplTest DreamOverlayCallbackControllerTest
DreamOverlayServiceTest KeyguardTransitionScenariosTest
DreamingToLockscreenTransitionViewModelTest
Bug: 195430376

Change-Id: I096a174729574964cc54fcf5a01522360491693c
parent 42153dae
Loading
Loading
Loading
Loading
+14 −16
Original line number Diff line number Diff line
@@ -101,13 +101,11 @@ constructor(
                            transitionViewModel.dreamOverlayTranslationY(it.translationYPx)
                        }
                        .collect { px ->
                            setElementsTranslationYAtPosition(
                                px,
                                ComplicationLayoutParams.POSITION_TOP
                            )
                            setElementsTranslationYAtPosition(
                                px,
                                ComplicationLayoutParams.POSITION_BOTTOM
                            ComplicationLayoutParams.iteratePositions(
                                { position: Int ->
                                    setElementsTranslationYAtPosition(px, position)
                                },
                                POSITION_TOP or POSITION_BOTTOM
                            )
                        }
                }
@@ -115,15 +113,15 @@ constructor(
                /* Alpha animations, when moving from DREAMING->LOCKSCREEN state */
                launch {
                    transitionViewModel.dreamOverlayAlpha.collect { alpha ->
                        ComplicationLayoutParams.iteratePositions(
                            { position: Int ->
                                setElementsAlphaAtPosition(
                                    alpha = alpha,
                            position = ComplicationLayoutParams.POSITION_TOP,
                                    position = position,
                                    fadingOut = true,
                                )
                        setElementsAlphaAtPosition(
                            alpha = alpha,
                            position = ComplicationLayoutParams.POSITION_BOTTOM,
                            fadingOut = true,
                            },
                            POSITION_TOP or POSITION_BOTTOM
                        )
                    }
                }
+20 −7
Original line number Diff line number Diff line
@@ -20,26 +20,39 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.policy.CallbackController
import javax.inject.Inject

/** Dream-related callback information */
/** Dream overlay-related callback information */
@SysUISingleton
class DreamCallbackController @Inject constructor() :
    CallbackController<DreamCallbackController.DreamCallback> {
class DreamOverlayCallbackController @Inject constructor() :
    CallbackController<DreamOverlayCallbackController.Callback> {

    private val callbacks = mutableSetOf<DreamCallbackController.DreamCallback>()
    private val callbacks = mutableSetOf<DreamOverlayCallbackController.Callback>()

    override fun addCallback(callback: DreamCallbackController.DreamCallback) {
    var isDreaming = false
        private set

    override fun addCallback(callback: DreamOverlayCallbackController.Callback) {
        callbacks.add(callback)
    }

    override fun removeCallback(callback: DreamCallbackController.DreamCallback) {
    override fun removeCallback(callback: DreamOverlayCallbackController.Callback) {
        callbacks.remove(callback)
    }

    fun onWakeUp() {
        isDreaming = false
        callbacks.forEach { it.onWakeUp() }
    }

    interface DreamCallback {
    fun onStartDream() {
        isDreaming = true
        callbacks.forEach { it.onStartDream() }
    }

    interface Callback {
        /** Dream overlay has ended */
        fun onWakeUp()

        /** Dream overlay has started */
        fun onStartDream()
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
    // A controller for the dream overlay container view (which contains both the status bar and the
    // content area).
    private DreamOverlayContainerViewController mDreamOverlayContainerViewController;
    private final DreamCallbackController mDreamCallbackController;
    private final DreamOverlayCallbackController mDreamOverlayCallbackController;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    @Nullable
    private final ComponentName mLowLightDreamComponent;
@@ -134,7 +134,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
            UiEventLogger uiEventLogger,
            @Nullable @Named(LowLightDreamModule.LOW_LIGHT_DREAM_COMPONENT)
                    ComponentName lowLightDreamComponent,
            DreamCallbackController dreamCallbackController) {
            DreamOverlayCallbackController dreamOverlayCallbackController) {
        mContext = context;
        mExecutor = executor;
        mWindowManager = windowManager;
@@ -143,7 +143,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
        mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
        mStateController = stateController;
        mUiEventLogger = uiEventLogger;
        mDreamCallbackController = dreamCallbackController;
        mDreamOverlayCallbackController = dreamOverlayCallbackController;

        final ViewModelStore viewModelStore = new ViewModelStore();
        final Complication.Host host =
@@ -203,6 +203,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
                    dreamComponent != null && dreamComponent.equals(mLowLightDreamComponent));
            mUiEventLogger.log(DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START);

            mDreamOverlayCallbackController.onStartDream();
            mStarted = true;
        });
    }
@@ -219,7 +220,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
    public void onWakeUp(@NonNull Runnable onCompletedCallback) {
        mExecutor.execute(() -> {
            if (mDreamOverlayContainerViewController != null) {
                mDreamCallbackController.onWakeUp();
                mDreamOverlayCallbackController.onWakeUp();
                mDreamOverlayContainerViewController.wakeUp(onCompletedCallback, mExecutor);
            }
        });
+89 −49
Original line number Diff line number Diff line
@@ -29,8 +29,7 @@ import com.android.systemui.doze.DozeHost
import com.android.systemui.doze.DozeMachine
import com.android.systemui.doze.DozeTransitionCallback
import com.android.systemui.doze.DozeTransitionListener
import com.android.systemui.dreams.DreamCallbackController
import com.android.systemui.dreams.DreamCallbackController.DreamCallback
import com.android.systemui.dreams.DreamOverlayCallbackController
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
@@ -49,7 +48,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.merge

/** Defines interface for classes that encapsulate application state for the keyguard. */
interface KeyguardRepository {
@@ -81,6 +79,9 @@ interface KeyguardRepository {
     */
    val isKeyguardShowing: Flow<Boolean>

    /** Is an activity showing over the keyguard? */
    val isKeyguardOccluded: Flow<Boolean>

    /** Observable for the signal that keyguard is about to go away. */
    val isKeyguardGoingAway: Flow<Boolean>

@@ -107,6 +108,9 @@ interface KeyguardRepository {
     */
    val isDreaming: Flow<Boolean>

    /** Observable for whether the device is dreaming with an overlay, see [DreamOverlayService] */
    val isDreamingWithOverlay: Flow<Boolean>

    /**
     * Observable for the amount of doze we are currently in.
     *
@@ -179,7 +183,7 @@ constructor(
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    private val dozeTransitionListener: DozeTransitionListener,
    private val authController: AuthController,
    private val dreamCallbackController: DreamCallbackController,
    private val dreamOverlayCallbackController: DreamOverlayCallbackController,
) : KeyguardRepository {
    private val _animateBottomAreaDozingTransitions = MutableStateFlow(false)
    override val animateBottomAreaDozingTransitions =
@@ -191,7 +195,8 @@ constructor(
    private val _clockPosition = MutableStateFlow(Position(0, 0))
    override val clockPosition = _clockPosition.asStateFlow()

    override val isKeyguardShowing: Flow<Boolean> = conflatedCallbackFlow {
    override val isKeyguardShowing: Flow<Boolean> =
        conflatedCallbackFlow {
                val callback =
                    object : KeyguardStateController.Callback {
                        override fun onKeyguardShowingChanged() {
@@ -213,6 +218,32 @@ constructor(

                awaitClose { keyguardStateController.removeCallback(callback) }
            }
            .distinctUntilChanged()

    override val isKeyguardOccluded: Flow<Boolean> =
        conflatedCallbackFlow {
                val callback =
                    object : KeyguardStateController.Callback {
                        override fun onKeyguardShowingChanged() {
                            trySendWithFailureLogging(
                                keyguardStateController.isOccluded,
                                TAG,
                                "updated isKeyguardOccluded"
                            )
                        }
                    }

                keyguardStateController.addCallback(callback)
                // Adding the callback does not send an initial update.
                trySendWithFailureLogging(
                    keyguardStateController.isOccluded,
                    TAG,
                    "initial isKeyguardOccluded"
                )

                awaitClose { keyguardStateController.removeCallback(callback) }
            }
            .distinctUntilChanged()

    override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
        val callback =
@@ -279,8 +310,29 @@ constructor(
            }
            .distinctUntilChanged()

    override val isDreamingWithOverlay: Flow<Boolean> =
        conflatedCallbackFlow {
                val callback =
                    object : DreamOverlayCallbackController.Callback {
                        override fun onStartDream() {
                            trySendWithFailureLogging(true, TAG, "updated isDreamingWithOverlay")
                        }
                        override fun onWakeUp() {
                            trySendWithFailureLogging(false, TAG, "updated isDreamingWithOverlay")
                        }
                    }
                dreamOverlayCallbackController.addCallback(callback)
                trySendWithFailureLogging(
                    dreamOverlayCallbackController.isDreaming,
                    TAG,
                    "initial isDreamingWithOverlay",
                )

                awaitClose { dreamOverlayCallbackController.removeCallback(callback) }
            }
            .distinctUntilChanged()

    override val isDreaming: Flow<Boolean> =
        merge(
        conflatedCallbackFlow {
                val callback =
                    object : KeyguardUpdateMonitorCallback() {
@@ -296,19 +348,7 @@ constructor(
                )

                awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
                },
                conflatedCallbackFlow {
                    val callback =
                        object : DreamCallback {
                            override fun onWakeUp() {
                                trySendWithFailureLogging(false, TAG, "updated isDreaming")
                            }
            }
                    dreamCallbackController.addCallback(callback)

                    awaitClose { dreamCallbackController.removeCallback(callback) }
                }
            )
            .distinctUntilChanged()

    override val linearDozeAmount: Flow<Float> = conflatedCallbackFlow {
+4 −0
Original line number Diff line number Diff line
@@ -131,6 +131,10 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
    }

    override fun startTransition(info: TransitionInfo): UUID? {
        if (lastStep.from == info.from && lastStep.to == info.to) {
            Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
            return null
        }
        if (lastStep.transitionState != TransitionState.FINISHED) {
            Log.i(TAG, "Transition still active: $lastStep, canceling")
        }
Loading