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

Commit c52dcfa7 authored by Matt Pietal's avatar Matt Pietal Committed by Automerger Merge Worker
Browse files

Merge changes I645115ab,I73b51987,Id1b79253 into tm-qpr-dev am: 2c34290e

parents 662da881 2c34290e
Loading
Loading
Loading
Loading
+60 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.data.repository

import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.common.shared.model.Position
@@ -69,6 +70,9 @@ interface KeyguardRepository {
     */
    val isKeyguardShowing: Flow<Boolean>

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

    /** Observable for whether the bouncer is showing. */
    val isBouncerShowing: Flow<Boolean>

@@ -84,6 +88,14 @@ interface KeyguardRepository {
     */
    val isDozing: Flow<Boolean>

    /**
     * Observable for whether the device is dreaming.
     *
     * Dozing/AOD is a specific type of dream, but it is also possible for other non-systemui dreams
     * to be active, such as screensavers.
     */
    val isDreaming: Flow<Boolean>

    /**
     * Observable for the amount of doze we are currently in.
     *
@@ -176,6 +188,29 @@ constructor(
        awaitClose { keyguardStateController.removeCallback(callback) }
    }

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

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

        awaitClose { keyguardStateController.removeCallback(callback) }
    }

    override val isBouncerShowing: Flow<Boolean> = conflatedCallbackFlow {
        val callback =
            object : KeyguardStateController.Callback {
@@ -218,6 +253,25 @@ constructor(
            }
            .distinctUntilChanged()

    override val isDreaming: Flow<Boolean> =
        conflatedCallbackFlow {
                val callback =
                    object : KeyguardUpdateMonitorCallback() {
                        override fun onDreamingStateChanged(isDreaming: Boolean) {
                            trySendWithFailureLogging(isDreaming, TAG, "updated isDreaming")
                        }
                    }
                keyguardUpdateMonitor.registerCallback(callback)
                trySendWithFailureLogging(
                    keyguardUpdateMonitor.isDreaming,
                    TAG,
                    "initial isDreaming",
                )

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

    override val dozeAmount: Flow<Float> = conflatedCallbackFlow {
        val callback =
            object : StatusBarStateController.StateListener {
+42 −11
Original line number Diff line number Diff line
@@ -94,11 +94,13 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
     */
    private val _transitions =
        MutableSharedFlow<TransitionStep>(
            replay = 2,
            extraBufferCapacity = 10,
            onBufferOverflow = BufferOverflow.DROP_OLDEST
            onBufferOverflow = BufferOverflow.DROP_OLDEST,
        )
    override val transitions = _transitions.asSharedFlow().distinctUntilChanged()
    private var lastStep: TransitionStep = TransitionStep()
    private var lastAnimator: ValueAnimator? = null

    /*
     * When manual control of the transition is requested, a unique [UUID] is used as the handle
@@ -106,19 +108,39 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
     */
    private var updateTransitionId: UUID? = null

    init {
        // Seed with transitions signaling a boot into lockscreen state
        emitTransition(
            TransitionStep(
                KeyguardState.OFF,
                KeyguardState.LOCKSCREEN,
                0f,
                TransitionState.STARTED,
            )
        )
        emitTransition(
            TransitionStep(
                KeyguardState.OFF,
                KeyguardState.LOCKSCREEN,
                1f,
                TransitionState.FINISHED,
            )
        )
    }

    override fun startTransition(info: TransitionInfo): UUID? {
        if (lastStep.transitionState != TransitionState.FINISHED) {
            // Open questions:
            // * Queue of transitions? buffer of 1?
            // * Are transitions cancellable if a new one is triggered?
            // * What validation does this need to do?
            Log.wtf(TAG, "Transition still active: $lastStep")
            return null
            Log.i(TAG, "Transition still active: $lastStep, canceling")
        }

        val startingValue = 1f - lastStep.value
        lastAnimator?.cancel()
        lastAnimator = info.animator

        info.animator?.let { animator ->
            // An animator was provided, so use it to run the transition
            animator.setFloatValues(0f, 1f)
            animator.setFloatValues(startingValue, 1f)
            animator.duration = ((1f - startingValue) * animator.duration).toLong()
            val updateListener =
                object : AnimatorUpdateListener {
                    override fun onAnimationUpdate(animation: ValueAnimator) {
@@ -134,15 +156,24 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio
            val adapter =
                object : AnimatorListenerAdapter() {
                    override fun onAnimationStart(animation: Animator) {
                        emitTransition(TransitionStep(info, 0f, TransitionState.STARTED))
                        emitTransition(TransitionStep(info, startingValue, TransitionState.STARTED))
                    }
                    override fun onAnimationCancel(animation: Animator) {
                        Log.i(TAG, "Cancelling transition: $info")
                        endAnimation(animation, lastStep.value, TransitionState.CANCELED)
                    }
                    override fun onAnimationEnd(animation: Animator) {
                        emitTransition(TransitionStep(info, 1f, TransitionState.FINISHED))
                        endAnimation(animation, 1f, TransitionState.FINISHED)
                    }

                    private fun endAnimation(
                        animation: Animator,
                        value: Float,
                        state: TransitionState
                    ) {
                        emitTransition(TransitionStep(info, value, state))
                        animator.removeListener(this)
                        animator.removeUpdateListener(updateListener)
                        lastAnimator = null
                    }
                }
            animator.addListener(adapter)
+23 −7
Original line number Diff line number Diff line
@@ -20,10 +20,11 @@ import android.animation.ValueAnimator
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.WakefulnessModel.Companion.isSleepingOrStartingToSleep
import com.android.systemui.keyguard.shared.model.WakefulnessModel.Companion.isWakingOrStartingToWake
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -35,18 +36,30 @@ class AodLockscreenTransitionInteractor
@Inject
constructor(
    @Application private val scope: CoroutineScope,
    private val keyguardRepository: KeyguardRepository,
    private val keyguardInteractor: KeyguardInteractor,
    private val keyguardTransitionRepository: KeyguardTransitionRepository,
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
) : TransitionInteractor("AOD<->LOCKSCREEN") {

    override fun start() {
        scope.launch {
            keyguardRepository.isDozing
                .sample(keyguardTransitionInteractor.finishedKeyguardState, { a, b -> Pair(a, b) })
            /*
             * Listening to the startedKeyguardTransitionStep (last started step) allows this code
             * to interrupt an active transition, as long as they were either going to LOCKSCREEN or
             * AOD state. One example is when the user presses the power button in the middle of an
             * active transition.
             */
            keyguardInteractor.wakefulnessState
                .sample(
                    keyguardTransitionInteractor.startedKeyguardTransitionStep,
                    { a, b -> Pair(a, b) }
                )
                .collect { pair ->
                    val (isDozing, keyguardState) = pair
                    if (isDozing && keyguardState == KeyguardState.LOCKSCREEN) {
                    val (wakefulnessState, lastStartedStep) = pair
                    if (
                        isSleepingOrStartingToSleep(wakefulnessState) &&
                            lastStartedStep.to == KeyguardState.LOCKSCREEN
                    ) {
                        keyguardTransitionRepository.startTransition(
                            TransitionInfo(
                                name,
@@ -55,7 +68,10 @@ constructor(
                                getAnimator(),
                            )
                        )
                    } else if (!isDozing && keyguardState == KeyguardState.AOD) {
                    } else if (
                        isWakingOrStartingToWake(wakefulnessState) &&
                            lastStartedStep.to == KeyguardState.AOD
                    ) {
                        keyguardTransitionRepository.startTransition(
                            TransitionInfo(
                                name,
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.domain.interactor

import android.animation.ValueAnimator
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.util.kotlin.sample
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

@SysUISingleton
class BouncerToGoneTransitionInteractor
@Inject
constructor(
    @Application private val scope: CoroutineScope,
    private val keyguardInteractor: KeyguardInteractor,
    private val shadeRepository: ShadeRepository,
    private val keyguardTransitionRepository: KeyguardTransitionRepository,
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor
) : TransitionInteractor("BOUNCER->GONE") {

    private var transitionId: UUID? = null

    override fun start() {
        listenForKeyguardGoingAway()
    }

    private fun listenForKeyguardGoingAway() {
        scope.launch {
            keyguardInteractor.isKeyguardGoingAway
                .sample(keyguardTransitionInteractor.finishedKeyguardState, { a, b -> Pair(a, b) })
                .collect { pair ->
                    val (isKeyguardGoingAway, keyguardState) = pair
                    if (isKeyguardGoingAway && keyguardState == KeyguardState.BOUNCER) {
                        keyguardTransitionRepository.startTransition(
                            TransitionInfo(
                                ownerName = name,
                                from = KeyguardState.BOUNCER,
                                to = KeyguardState.GONE,
                                animator = getAnimator(),
                            )
                        )
                    }
                }
        }
    }

    private fun getAnimator(): ValueAnimator {
        return ValueAnimator().apply {
            setInterpolator(Interpolators.LINEAR)
            setDuration(TRANSITION_DURATION_MS)
        }
    }

    companion object {
        private const val TRANSITION_DURATION_MS = 300L
    }
}
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.domain.interactor

import android.animation.ValueAnimator
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

@SysUISingleton
class DreamingLockscreenTransitionInteractor
@Inject
constructor(
    @Application private val scope: CoroutineScope,
    private val keyguardInteractor: KeyguardInteractor,
    private val keyguardTransitionRepository: KeyguardTransitionRepository,
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
) : TransitionInteractor("DREAMING<->LOCKSCREEN") {

    override fun start() {
        scope.launch {
            keyguardInteractor.isDreaming
                .sample(keyguardTransitionInteractor.finishedKeyguardState, { a, b -> Pair(a, b) })
                .collect { pair ->
                    val (isDreaming, keyguardState) = pair
                    if (isDreaming && keyguardState == KeyguardState.LOCKSCREEN) {
                        keyguardTransitionRepository.startTransition(
                            TransitionInfo(
                                name,
                                KeyguardState.LOCKSCREEN,
                                KeyguardState.DREAMING,
                                getAnimator(),
                            )
                        )
                    } else if (!isDreaming && keyguardState == KeyguardState.DREAMING) {
                        keyguardTransitionRepository.startTransition(
                            TransitionInfo(
                                name,
                                KeyguardState.DREAMING,
                                KeyguardState.LOCKSCREEN,
                                getAnimator(),
                            )
                        )
                    }
                }
        }
    }

    private fun getAnimator(): ValueAnimator {
        return ValueAnimator().apply {
            setInterpolator(Interpolators.LINEAR)
            setDuration(TRANSITION_DURATION_MS)
        }
    }

    companion object {
        private const val TRANSITION_DURATION_MS = 500L
    }
}
Loading