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

Commit 030b7809 authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge "[DO NOT MERGE] Bouncer - Intercept touch events when not visible" into tm-qpr-dev

parents 5daa52fd 96cdb8a2
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.keyguard;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;

/**
@@ -33,7 +34,7 @@ import android.widget.FrameLayout;
public class KeyguardHostView extends FrameLayout {

    protected ViewMediatorCallback mViewMediatorCallback;

    private boolean mIsInteractable;

    public KeyguardHostView(Context context) {
        this(context, null);
@@ -54,4 +55,24 @@ public class KeyguardHostView extends FrameLayout {
    public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
        mViewMediatorCallback = viewMediatorCallback;
    }

    /** Set true if the view can be interacted with */
    public void setInteractable(boolean isInteractable) {
        mIsInteractable = isInteractable;
    }

    /**
     * Make sure to disallow touches while transitioning the bouncer, otherwise
     * it can remain interactable even when barely visible.
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return !mIsInteractable;
    }

    /** True to consume any events that are sent to it */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -527,4 +527,9 @@ public class KeyguardHostViewController extends ViewController<KeyguardHostView>
            mKeyguardSecurityContainerController.updateKeyguardPosition(x);
        }
    }

    /** Set true if the view can be interacted with */
    public void setInteractable(boolean isInteractable) {
        mView.setInteractable(isInteractable);
    }
}
+102 −37
Original line number Diff line number Diff line
@@ -41,31 +41,96 @@ import kotlinx.coroutines.flow.map
 *
 * Make sure to add newly added flows to the logger.
 */
interface KeyguardBouncerRepository {
    /** Values associated with the PrimaryBouncer (pin/pattern/password) input. */
    val primaryBouncerVisible: StateFlow<Boolean>
    val primaryBouncerShow: StateFlow<KeyguardBouncerModel?>
    val primaryBouncerShowingSoon: StateFlow<Boolean>
    val primaryBouncerHide: StateFlow<Boolean>
    val primaryBouncerStartingToHide: StateFlow<Boolean>
    val primaryBouncerStartingDisappearAnimation: StateFlow<Runnable?>
    /** Determines if we want to instantaneously show the primary bouncer instead of translating. */
    val primaryBouncerScrimmed: StateFlow<Boolean>
    /**
     * Set how much of the notification panel is showing on the screen.
     * ```
     *      0f = panel fully hidden = bouncer fully showing
     *      1f = panel fully showing = bouncer fully hidden
     * ```
     */
    val panelExpansionAmount: StateFlow<Float>
    val keyguardPosition: StateFlow<Float>
    val onScreenTurnedOff: StateFlow<Boolean>
    val isBackButtonEnabled: StateFlow<Boolean?>
    /** Determines if user is already unlocked */
    val keyguardAuthenticated: StateFlow<Boolean?>
    val showMessage: StateFlow<BouncerShowMessageModel?>
    val resourceUpdateRequests: StateFlow<Boolean>
    val bouncerPromptReason: Int
    val bouncerErrorMessage: CharSequence?
    val isAlternateBouncerVisible: StateFlow<Boolean>
    val isAlternateBouncerUIAvailable: StateFlow<Boolean>
    var lastAlternateBouncerVisibleTime: Long

    fun setPrimaryScrimmed(isScrimmed: Boolean)

    fun setPrimaryVisible(isVisible: Boolean)

    fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?)

    fun setPrimaryShowingSoon(showingSoon: Boolean)

    fun setPrimaryHide(hide: Boolean)

    fun setPrimaryStartingToHide(startingToHide: Boolean)

    fun setPrimaryStartDisappearAnimation(runnable: Runnable?)

    fun setPanelExpansion(panelExpansion: Float)

    fun setKeyguardPosition(keyguardPosition: Float)

    fun setResourceUpdateRequests(willUpdateResources: Boolean)

    fun setShowMessage(bouncerShowMessageModel: BouncerShowMessageModel?)

    fun setKeyguardAuthenticated(keyguardAuthenticated: Boolean?)

    fun setIsBackButtonEnabled(isBackButtonEnabled: Boolean)

    fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean)

    fun setAlternateVisible(isVisible: Boolean)

    fun setAlternateBouncerUIAvailable(isAvailable: Boolean)
}

@SysUISingleton
class KeyguardBouncerRepository
class KeyguardBouncerRepositoryImpl
@Inject
constructor(
    private val viewMediatorCallback: ViewMediatorCallback,
    private val clock: SystemClock,
    @Application private val applicationScope: CoroutineScope,
    @BouncerLog private val buffer: TableLogBuffer,
) {
) : KeyguardBouncerRepository {
    /** Values associated with the PrimaryBouncer (pin/pattern/password) input. */
    private val _primaryBouncerVisible = MutableStateFlow(false)
    val primaryBouncerVisible = _primaryBouncerVisible.asStateFlow()
    override val primaryBouncerVisible = _primaryBouncerVisible.asStateFlow()
    private val _primaryBouncerShow = MutableStateFlow<KeyguardBouncerModel?>(null)
    val primaryBouncerShow = _primaryBouncerShow.asStateFlow()
    override val primaryBouncerShow = _primaryBouncerShow.asStateFlow()
    private val _primaryBouncerShowingSoon = MutableStateFlow(false)
    val primaryBouncerShowingSoon = _primaryBouncerShowingSoon.asStateFlow()
    override val primaryBouncerShowingSoon = _primaryBouncerShowingSoon.asStateFlow()
    private val _primaryBouncerHide = MutableStateFlow(false)
    val primaryBouncerHide = _primaryBouncerHide.asStateFlow()
    override val primaryBouncerHide = _primaryBouncerHide.asStateFlow()
    private val _primaryBouncerStartingToHide = MutableStateFlow(false)
    val primaryBouncerStartingToHide = _primaryBouncerStartingToHide.asStateFlow()
    override val primaryBouncerStartingToHide = _primaryBouncerStartingToHide.asStateFlow()
    private val _primaryBouncerDisappearAnimation = MutableStateFlow<Runnable?>(null)
    val primaryBouncerStartingDisappearAnimation = _primaryBouncerDisappearAnimation.asStateFlow()
    override val primaryBouncerStartingDisappearAnimation =
        _primaryBouncerDisappearAnimation.asStateFlow()
    /** Determines if we want to instantaneously show the primary bouncer instead of translating. */
    private val _primaryBouncerScrimmed = MutableStateFlow(false)
    val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow()
    override val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow()
    /**
     * Set how much of the notification panel is showing on the screen.
     * ```
@@ -74,23 +139,23 @@ constructor(
     * ```
     */
    private val _panelExpansionAmount = MutableStateFlow(EXPANSION_HIDDEN)
    val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
    override val panelExpansionAmount = _panelExpansionAmount.asStateFlow()
    private val _keyguardPosition = MutableStateFlow(0f)
    val keyguardPosition = _keyguardPosition.asStateFlow()
    override val keyguardPosition = _keyguardPosition.asStateFlow()
    private val _onScreenTurnedOff = MutableStateFlow(false)
    val onScreenTurnedOff = _onScreenTurnedOff.asStateFlow()
    override val onScreenTurnedOff = _onScreenTurnedOff.asStateFlow()
    private val _isBackButtonEnabled = MutableStateFlow<Boolean?>(null)
    val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow()
    override val isBackButtonEnabled = _isBackButtonEnabled.asStateFlow()
    private val _keyguardAuthenticated = MutableStateFlow<Boolean?>(null)
    /** Determines if user is already unlocked */
    val keyguardAuthenticated = _keyguardAuthenticated.asStateFlow()
    override val keyguardAuthenticated = _keyguardAuthenticated.asStateFlow()
    private val _showMessage = MutableStateFlow<BouncerShowMessageModel?>(null)
    val showMessage = _showMessage.asStateFlow()
    override val showMessage = _showMessage.asStateFlow()
    private val _resourceUpdateRequests = MutableStateFlow(false)
    val resourceUpdateRequests = _resourceUpdateRequests.asStateFlow()
    val bouncerPromptReason: Int
    override val resourceUpdateRequests = _resourceUpdateRequests.asStateFlow()
    override val bouncerPromptReason: Int
        get() = viewMediatorCallback.bouncerPromptReason
    val bouncerErrorMessage: CharSequence?
    override val bouncerErrorMessage: CharSequence?
        get() = viewMediatorCallback.consumeCustomMessage()

    init {
@@ -99,21 +164,21 @@ constructor(

    /** Values associated with the AlternateBouncer */
    private val _isAlternateBouncerVisible = MutableStateFlow(false)
    val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
    var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
    override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
    override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
    private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
    val isAlternateBouncerUIAvailable: StateFlow<Boolean> =
    override val isAlternateBouncerUIAvailable: StateFlow<Boolean> =
        _isAlternateBouncerUIAvailable.asStateFlow()

    fun setPrimaryScrimmed(isScrimmed: Boolean) {
    override fun setPrimaryScrimmed(isScrimmed: Boolean) {
        _primaryBouncerScrimmed.value = isScrimmed
    }

    fun setPrimaryVisible(isVisible: Boolean) {
    override fun setPrimaryVisible(isVisible: Boolean) {
        _primaryBouncerVisible.value = isVisible
    }

    fun setAlternateVisible(isVisible: Boolean) {
    override fun setAlternateVisible(isVisible: Boolean) {
        if (isVisible && !_isAlternateBouncerVisible.value) {
            lastAlternateBouncerVisibleTime = clock.uptimeMillis()
        } else if (!isVisible) {
@@ -122,55 +187,55 @@ constructor(
        _isAlternateBouncerVisible.value = isVisible
    }

    fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
    override fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
        _isAlternateBouncerUIAvailable.value = isAvailable
    }

    fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) {
    override fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) {
        _primaryBouncerShow.value = keyguardBouncerModel
    }

    fun setPrimaryShowingSoon(showingSoon: Boolean) {
    override fun setPrimaryShowingSoon(showingSoon: Boolean) {
        _primaryBouncerShowingSoon.value = showingSoon
    }

    fun setPrimaryHide(hide: Boolean) {
    override fun setPrimaryHide(hide: Boolean) {
        _primaryBouncerHide.value = hide
    }

    fun setPrimaryStartingToHide(startingToHide: Boolean) {
    override fun setPrimaryStartingToHide(startingToHide: Boolean) {
        _primaryBouncerStartingToHide.value = startingToHide
    }

    fun setPrimaryStartDisappearAnimation(runnable: Runnable?) {
    override fun setPrimaryStartDisappearAnimation(runnable: Runnable?) {
        _primaryBouncerDisappearAnimation.value = runnable
    }

    fun setPanelExpansion(panelExpansion: Float) {
    override fun setPanelExpansion(panelExpansion: Float) {
        _panelExpansionAmount.value = panelExpansion
    }

    fun setKeyguardPosition(keyguardPosition: Float) {
    override fun setKeyguardPosition(keyguardPosition: Float) {
        _keyguardPosition.value = keyguardPosition
    }

    fun setResourceUpdateRequests(willUpdateResources: Boolean) {
    override fun setResourceUpdateRequests(willUpdateResources: Boolean) {
        _resourceUpdateRequests.value = willUpdateResources
    }

    fun setShowMessage(bouncerShowMessageModel: BouncerShowMessageModel?) {
    override fun setShowMessage(bouncerShowMessageModel: BouncerShowMessageModel?) {
        _showMessage.value = bouncerShowMessageModel
    }

    fun setKeyguardAuthenticated(keyguardAuthenticated: Boolean?) {
    override fun setKeyguardAuthenticated(keyguardAuthenticated: Boolean?) {
        _keyguardAuthenticated.value = keyguardAuthenticated
    }

    fun setIsBackButtonEnabled(isBackButtonEnabled: Boolean) {
    override fun setIsBackButtonEnabled(isBackButtonEnabled: Boolean) {
        _isBackButtonEnabled.value = isBackButtonEnabled
    }

    fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) {
    override fun setOnScreenTurnedOff(onScreenTurnedOff: Boolean) {
        _onScreenTurnedOff.value = onScreenTurnedOff
    }

+3 −0
Original line number Diff line number Diff line
@@ -37,4 +37,7 @@ interface KeyguardRepositoryModule {
    fun deviceEntryFingerprintAuthRepository(
        impl: DeviceEntryFingerprintAuthRepositoryImpl
    ): DeviceEntryFingerprintAuthRepository

    @Binds
    fun keyguardBouncerRepository(impl: KeyguardBouncerRepositoryImpl): KeyguardBouncerRepository
}
+2 −0
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@ constructor(
                0f
            }
        }
    /** Allow for interaction when just about fully visible */
    val isInteractable: Flow<Boolean> = bouncerExpansion.map { it > 0.9 }

    // TODO(b/243685699): Move isScrimmed logic to data layer.
    // TODO(b/243695312): Encapsulate all of the show logic for the bouncer.
Loading