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

Commit ee354c9b authored by Bharat Singh's avatar Bharat Singh
Browse files

[SysUI][Floaty] Move power button pressed and long pressed to StateFlow

Power button down event is subscribed by multiple consumers, moving to
StateFlow ensures that all consumers receive same updated latest value.

Bug: 399263897
Flag: com.android.systemui.shared.enable_lpp_squeeze_effect
Test: atest KeyEventRepositoryTest
Change-Id: I0fb775579425af69171db468e19dbb7ddd47c39d
parent 928b7963
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.keyevent.data.repository.KeyEventRepositoryImpl
import com.android.systemui.statusbar.CommandQueue
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -51,7 +52,10 @@ class KeyEventRepositoryTest : SysuiTestCase() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        testScope = TestScope()
        underTest = KeyEventRepositoryImpl(commandQueue)
        underTest = KeyEventRepositoryImpl(
            commandQueue = commandQueue,
            applicationScope = testScope.backgroundScope
        )
    }

    @Test
@@ -65,8 +69,7 @@ class KeyEventRepositoryTest : SysuiTestCase() {
    @Test
    fun isPowerButtonBeingLongPressed_initialValueFalse() =
        testScope.runTest {
            val isPowerButtonLongPressed by collectLastValue(
                underTest.isPowerButtonLongPressed)
            val isPowerButtonLongPressed by collectLastValue(underTest.isPowerButtonLongPressed)
            runCurrent()
            assertThat(isPowerButtonLongPressed).isFalse()
        }
@@ -74,26 +77,34 @@ class KeyEventRepositoryTest : SysuiTestCase() {
    @Test
    fun isPowerButtonDown_onChange() =
        testScope.runTest {
            val isPowerButtonDown by collectLastValue(underTest.isPowerButtonDown)
            underTest.isPowerButtonDown.launchIn(testScope.backgroundScope)

            runCurrent()

            verify(commandQueue).addCallback(commandQueueCallbacks.capture())

            commandQueueCallbacks.value.handleSystemKey(
                KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER)
            )
            assertThat(isPowerButtonDown).isTrue()

            runCurrent()

            assertThat(underTest.isPowerButtonDown.value).isTrue()

            commandQueueCallbacks.value.handleSystemKey(
                KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_POWER)
            )
            assertThat(isPowerButtonDown).isFalse()

            runCurrent()

            assertThat(underTest.isPowerButtonDown.value).isFalse()
        }


    @Test
    fun isPowerButtonBeingLongPressed_onPowerButtonDown() =
        testScope.runTest {
            val isPowerButtonLongPressed by collectLastValue(
                underTest.isPowerButtonLongPressed)
            underTest.isPowerButtonLongPressed.launchIn(testScope.backgroundScope)

            runCurrent()

@@ -102,14 +113,15 @@ class KeyEventRepositoryTest : SysuiTestCase() {
            val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_POWER)
            commandQueueCallbacks.value.handleSystemKey(keyEvent)

            assertThat(isPowerButtonLongPressed).isFalse()
            runCurrent()

            assertThat(underTest.isPowerButtonLongPressed.value).isFalse()
        }

    @Test
    fun isPowerButtonBeingLongPressed_onPowerButtonUp() =
        testScope.runTest {
            val isPowerButtonLongPressed by collectLastValue(
                underTest.isPowerButtonLongPressed)
            underTest.isPowerButtonLongPressed.launchIn(testScope.backgroundScope)

            runCurrent()

@@ -118,14 +130,15 @@ class KeyEventRepositoryTest : SysuiTestCase() {
            val keyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_POWER)
            commandQueueCallbacks.value.handleSystemKey(keyEvent)

            assertThat(isPowerButtonLongPressed).isFalse()
            runCurrent()

            assertThat(underTest.isPowerButtonLongPressed.value).isFalse()
        }

    @Test
    fun isPowerButtonBeingLongPressed_onPowerButtonDown_longPressFlagSet() =
        testScope.runTest {
            val isPowerButtonBeingLongPressed by collectLastValue(
                underTest.isPowerButtonLongPressed)
            underTest.isPowerButtonLongPressed.launchIn(testScope.backgroundScope)

            runCurrent()

@@ -135,6 +148,8 @@ class KeyEventRepositoryTest : SysuiTestCase() {
            keyEvent.setFlags(KeyEvent.FLAG_LONG_PRESS)
            commandQueueCallbacks.value.handleSystemKey(keyEvent)

            assertThat(isPowerButtonBeingLongPressed).isTrue()
            runCurrent()

            assertThat(underTest.isPowerButtonLongPressed.value).isTrue()
        }
}
+44 −28
Original line number Diff line number Diff line
@@ -18,20 +18,24 @@ package com.android.systemui.keyevent.data.repository

import android.view.KeyEvent
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.statusbar.CommandQueue
import javax.inject.Inject
import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject

/** Defines interface for classes that encapsulate application state for key event presses. */
interface KeyEventRepository {
    /** Observable for whether the power button key is pressed/down or not. */
    val isPowerButtonDown: Flow<Boolean>
    val isPowerButtonDown: StateFlow<Boolean>

    /** Observable for when the power button is being pressed but till the duration of long press */
    val isPowerButtonLongPressed: Flow<Boolean>
    val isPowerButtonLongPressed: StateFlow<Boolean>
}

@SysUISingleton
@@ -39,13 +43,15 @@ class KeyEventRepositoryImpl
@Inject
constructor(
    private val commandQueue: CommandQueue,
    @Application applicationScope: CoroutineScope
) : KeyEventRepository {
    override val isPowerButtonDown: Flow<Boolean> = conflatedCallbackFlow {
        val callback =
            object : CommandQueue.Callbacks {
    override val isPowerButtonDown =
        conflatedCallbackFlow {
            val callback = object : CommandQueue.Callbacks {
                    override fun handleSystemKey(event: KeyEvent) {
                        if (event.keyCode == KeyEvent.KEYCODE_POWER) {
                        trySendWithFailureLogging(event.isDown, TAG, "updated isPowerButtonDown")
                            trySendWithFailureLogging(event.action == KeyEvent.ACTION_DOWN,
                                TAG, "updated isPowerButtonDown")
                        }
                    }
                }
@@ -53,10 +59,15 @@ constructor(
            commandQueue.addCallback(callback)
            awaitClose { commandQueue.removeCallback(callback) }
        }
        .stateIn(
            scope = applicationScope,
            started = SharingStarted.WhileSubscribed(),
            initialValue = false
        )

    override val isPowerButtonLongPressed: Flow<Boolean> = conflatedCallbackFlow {
        val callback =
            object : CommandQueue.Callbacks {
    override val isPowerButtonLongPressed =
        conflatedCallbackFlow {
            val callback = object : CommandQueue.Callbacks {
                    override fun handleSystemKey(event: KeyEvent) {
                        if (event.keyCode == KeyEvent.KEYCODE_POWER) {
                            trySendWithFailureLogging(event.action == KeyEvent.ACTION_DOWN
@@ -68,6 +79,11 @@ constructor(
            commandQueue.addCallback(callback)
            awaitClose { commandQueue.removeCallback(callback) }
        }
        .stateIn(
            scope = applicationScope,
            started = SharingStarted.WhileSubscribed(),
            initialValue = false
        )

    companion object {
        private const val TAG = "KeyEventRepositoryImpl"
+3 −3
Original line number Diff line number Diff line
@@ -18,14 +18,14 @@ package com.android.systemui.keyevent.data.repository

import dagger.Binds
import dagger.Module
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject

class FakeKeyEventRepository @Inject constructor() : KeyEventRepository {
    private val _isPowerButtonDown = MutableStateFlow(false)
    override val isPowerButtonDown: Flow<Boolean> = _isPowerButtonDown.asStateFlow()
    override val isPowerButtonDown: StateFlow<Boolean> = _isPowerButtonDown.asStateFlow()

    private val _isPowerButtonLongPressed = MutableStateFlow(false)
    override val isPowerButtonLongPressed = _isPowerButtonLongPressed.asStateFlow()