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

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

Merge "Add UNDEFINED KTF state and tie it to STL transitions" into main

parents 5a63dc06 61d14d94
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ constructor(
        state: TransitionState
    ) {
        if (updateTransitionId != transitionId) {
            Log.wtf(TAG, "Attempting to update with old/invalid transitionId: $transitionId")
            Log.w(TAG, "Attempting to update with old/invalid transitionId: $transitionId")
            return
        }

+37 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.keyguard.data.repository

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.KeyguardState
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow

@SysUISingleton
class LockscreenSceneTransitionRepository @Inject constructor() {

    /**
     * This [KeyguardState] will indicate which sub state within KTF should be navigated to when the
     * next transition into the Lockscreen scene is started. It will be consumed exactly once and
     * after that the state will be set back to [DEFAULT_STATE].
     */
    val nextLockscreenTargetState: MutableStateFlow<KeyguardState> = MutableStateFlow(DEFAULT_STATE)

    companion object {
        val DEFAULT_STATE = KeyguardState.LOCKSCREEN
    }
}
+34 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@

package com.android.systemui.keyguard.domain.interactor

import android.annotation.FloatRange
import android.annotation.SuppressLint
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -34,6 +36,7 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.util.kotlin.pairwise
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -76,6 +79,8 @@ constructor(
     * single state. This prevent the redundant filters from running.
     */
    private val transitionValueCache = mutableMapOf<KeyguardState, MutableSharedFlow<Float>>()

    @SuppressLint("SharedFlowCreation")
    private fun getTransitionValueFlow(state: KeyguardState): MutableSharedFlow<Float> {
        return transitionValueCache.getOrPut(state) {
            MutableSharedFlow<Float>(
@@ -90,6 +95,9 @@ constructor(
    @Deprecated("Not performant - Use something else in this class")
    val transitions = repository.transitions

    val transitionState: StateFlow<TransitionStep> =
        transitions.stateIn(scope, SharingStarted.Eagerly, TransitionStep())

    /**
     * A pair of the most recent STARTED step, and the transition step immediately preceding it. The
     * transition framework enforces that the previous step is either a CANCELED or FINISHED step,
@@ -99,6 +107,7 @@ constructor(
     * FINISHED. In the case of a CANCELED step, we can also figure out which state we were coming
     * from when we were canceled.
     */
    @SuppressLint("SharedFlowCreation")
    val startedStepWithPrecedingStep =
        repository.transitions
            .pairwise()
@@ -144,9 +153,10 @@ constructor(
    }

    /** Given an [edge], return a SharedFlow to collect only relevant [TransitionStep]. */
    @SuppressLint("SharedFlowCreation")
    fun getOrCreateFlow(edge: Edge): MutableSharedFlow<TransitionStep> {
        return transitionMap.getOrPut(edge) {
            MutableSharedFlow<TransitionStep>(
            MutableSharedFlow(
                extraBufferCapacity = 10,
                onBufferOverflow = BufferOverflow.DROP_OLDEST
            )
@@ -180,6 +190,7 @@ constructor(
     * AOD<->* transition information, mapped to dozeAmount range of AOD (1f) <->
     * * (0f).
     */
    @SuppressLint("SharedFlowCreation")
    val dozeAmountTransition: Flow<TransitionStep> =
        repository.transitions
            .filter { step -> step.from == AOD || step.to == AOD }
@@ -201,11 +212,20 @@ constructor(
        repository.transitions.filter { step -> step.transitionState == TransitionState.FINISHED }

    /** The destination state of the last [TransitionState.STARTED] transition. */
    @SuppressLint("SharedFlowCreation")
    val startedKeyguardState: SharedFlow<KeyguardState> =
        startedKeyguardTransitionStep
            .map { step -> step.to }
            .shareIn(scope, SharingStarted.Eagerly, replay = 1)

    /** The from state of the last [TransitionState.STARTED] transition. */
    // TODO: is it performant to have several SharedFlows side by side instead of one?
    @SuppressLint("SharedFlowCreation")
    val startedKeyguardFromState: SharedFlow<KeyguardState> =
        startedKeyguardTransitionStep
            .map { step -> step.from }
            .shareIn(scope, SharingStarted.Eagerly, replay = 1)

    /** Which keyguard state to use when the device goes to sleep. */
    val asleepKeyguardState: StateFlow<KeyguardState> =
        keyguardRepository.isAodAvailable
@@ -243,6 +263,7 @@ constructor(
     * sufficient. However, if you're having issues with state *during* transitions started after
     * one or more canceled transitions, you probably need to use [currentKeyguardState].
     */
    @SuppressLint("SharedFlowCreation")
    val finishedKeyguardState: SharedFlow<KeyguardState> =
        finishedKeyguardTransitionStep
            .map { step -> step.to }
@@ -491,7 +512,19 @@ constructor(
        return startedKeyguardState.replayCache.last()
    }

    fun getStartedFromState(): KeyguardState {
        return startedKeyguardFromState.replayCache.last()
    }

    fun getFinishedState(): KeyguardState {
        return finishedKeyguardState.replayCache.last()
    }

    suspend fun startTransition(info: TransitionInfo) = repository.startTransition(info)

    fun updateTransition(
        transitionId: UUID,
        @FloatRange(from = 0.0, to = 1.0) value: Float,
        state: TransitionState
    ) = repository.updateTransition(transitionId, value, state)
}
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ constructor(
            KeyguardState.LOCKSCREEN -> true
            KeyguardState.GONE -> true
            KeyguardState.OCCLUDED -> true
            KeyguardState.UNDEFINED -> true
        }
    }

+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor

import com.android.systemui.CoreStartable
import com.android.systemui.keyguard.domain.interactor.scenetransition.LockscreenSceneTransitionInteractor
import dagger.Binds
import dagger.Module
import dagger.multibindings.ClassKey
@@ -30,6 +31,13 @@ abstract class StartKeyguardTransitionModule {
    @ClassKey(KeyguardTransitionCoreStartable::class)
    abstract fun bind(impl: KeyguardTransitionCoreStartable): CoreStartable

    @Binds
    @IntoMap
    @ClassKey(LockscreenSceneTransitionInteractor::class)
    abstract fun bindLockscreenSceneTransitionInteractor(
        impl: LockscreenSceneTransitionInteractor
    ): CoreStartable

    @Binds
    @IntoSet
    abstract fun fromPrimaryBouncer(
Loading