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

Commit 5af41e1d authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Support KeyEvent.KEYCODE_ENTER on the keyguard

Attempt #2

On the keyguard, when there's a keyEvent for KEYCODE_ENTER
on action up (not down):
  - If the notification shade is expanded, the notification
    shade will collapse.
  - If the notification shade is not expanded, the primary
    bouncer will show if it's not already showing.

This also updates the logic for the menu and space keycodes to
show the above logic instead of generically collapsing the
notification shade in both cases (which would show the alternate
bouncer instead of the primary bouncer).

Test: `adb shell input keyevent KEYCODE_SPACE`, `KEYCODE_MENU`
and `KEYCODE_ENTER` will dismiss the lockscreen if there's no security,
else the primary bouncer will show. If the notification shade is
expanded on the lockscreen, these commands will collapse the shade.
Test: atest KeyguardKeyEventInteractorTest
Fixes: 270883077

Change-Id: I9d3444dee0149d579a5d3a6d85eac183eeeeba33
parent 21b5b8a3
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -29,8 +29,10 @@ import com.android.systemui.shade.ShadeController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi

/** Handles key events arriving when the keyguard is showing or device is dozing. */
@ExperimentalCoroutinesApi
@SysUISingleton
class KeyguardKeyEventInteractor
@Inject
@@ -56,7 +58,11 @@ constructor(
        if (event.handleAction()) {
            when (event.keyCode) {
                KeyEvent.KEYCODE_MENU -> return dispatchMenuKeyEvent()
                KeyEvent.KEYCODE_SPACE -> return dispatchSpaceEvent()
                KeyEvent.KEYCODE_SPACE,
                KeyEvent.KEYCODE_ENTER ->
                    if (isDeviceAwake()) {
                        return collapseShadeLockedOrShowPrimaryBouncer()
                    }
            }
        }
        return false
@@ -92,17 +98,25 @@ constructor(
                (statusBarStateController.state != StatusBarState.SHADE) &&
                statusBarKeyguardViewManager.shouldDismissOnMenuPressed()
        if (shouldUnlockOnMenuPressed) {
            shadeController.animateCollapseShadeForced()
            return true
            return collapseShadeLockedOrShowPrimaryBouncer()
        }
        return false
    }

    private fun dispatchSpaceEvent(): Boolean {
        if (isDeviceAwake() && statusBarStateController.state != StatusBarState.SHADE) {
    private fun collapseShadeLockedOrShowPrimaryBouncer(): Boolean {
        when (statusBarStateController.state) {
            StatusBarState.SHADE -> return false
            StatusBarState.SHADE_LOCKED -> {
                shadeController.animateCollapseShadeForced()
                return true
            }
            StatusBarState.KEYGUARD -> {
                if (!statusBarKeyguardViewManager.primaryBouncerIsShowing()) {
                    statusBarKeyguardViewManager.showPrimaryBouncer(true)
                    return true
                }
            }
        }
        return false
    }

+82 −27
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -46,6 +47,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

@ExperimentalCoroutinesApi
@SmallTest
@RunWith(AndroidJUnit4::class)
class KeyguardKeyEventInteractorTest : SysuiTestCase() {
@@ -132,58 +134,73 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
    }

    @Test
    fun dispatchKeyEvent_menuActionUp_interactiveKeyguard_collapsesShade() {
    fun dispatchKeyEvent_menuActionUp_awakeKeyguard_showsPrimaryBouncer() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
        whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)

        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
        verify(shadeController).animateCollapseShadeForced()
        verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_MENU)
    }

    @Test
    fun dispatchKeyEvent_menuActionUp_interactiveShadeLocked_collapsesShade() {
    fun dispatchKeyEvent_menuActionUp_awakeShadeLocked_collapsesShade() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
        whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)

        // action down: does NOT collapse the shade
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()

        // action up: collapses the shade
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
        verify(shadeController).animateCollapseShadeForced()
        verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_MENU)
    }

    @Test
    fun dispatchKeyEvent_menuActionUp_nonInteractiveKeyguard_neverCollapsesShade() {
    fun dispatchKeyEvent_menuActionUp_asleepKeyguard_neverCollapsesShade() {
        powerInteractor.setAsleepForTest()
        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
        whenever(statusBarKeyguardViewManager.shouldDismissOnMenuPressed()).thenReturn(true)

        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()
        verifyActionsDoNothing(KeyEvent.KEYCODE_MENU)
    }

    @Test
    fun dispatchKeyEvent_spaceActionUp_interactiveKeyguard_collapsesShade() {
    fun dispatchKeyEvent_spaceActionUp_awakeKeyguard_collapsesShade() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
        whenever(statusBarKeyguardViewManager.primaryBouncerIsShowing()).thenReturn(false)

        // action down: does NOT collapse the shade
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_SPACE)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()
        verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_SPACE)
    }

        // action up: collapses the shade
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
        verify(shadeController).animateCollapseShadeForced()
    @Test
    fun dispatchKeyEvent_spaceActionUp_shadeLocked_collapsesShade() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)

        verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_SPACE)
    }

    @Test
    fun dispatchKeyEvent_enterActionUp_awakeKeyguard_showsPrimaryBouncer() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarKeyguardViewManager.primaryBouncerIsShowing()).thenReturn(false)
        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)

        verifyActionUpShowsPrimaryBouncer(KeyEvent.KEYCODE_ENTER)
    }

    @Test
    fun dispatchKeyEvent_enterActionUp_awakeKeyguard_primaryBouncerAlreadyShowing() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarKeyguardViewManager.primaryBouncerIsShowing()).thenReturn(true)
        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)

        verifyActionsDoNothing(KeyEvent.KEYCODE_ENTER)
    }

    @Test
    fun dispatchKeyEvent_enterActionUp_shadeLocked_collapsesShade() {
        powerInteractor.setAwakeForTest()
        whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)

        verifyActionUpCollapsesTheShade(KeyEvent.KEYCODE_ENTER)
    }

    @Test
@@ -253,4 +270,42 @@ class KeyguardKeyEventInteractorTest : SysuiTestCase() {
            .isFalse()
        verify(statusBarKeyguardViewManager, never()).interceptMediaKey(any())
    }

    private fun verifyActionUpCollapsesTheShade(keycode: Int) {
        // action down: does NOT collapse the shade
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()

        // action up: collapses the shade
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
        verify(shadeController).animateCollapseShadeForced()
    }

    private fun verifyActionUpShowsPrimaryBouncer(keycode: Int) {
        // action down: does NOT collapse the shade
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())

        // action up: collapses the shade
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isTrue()
        verify(statusBarKeyguardViewManager).showPrimaryBouncer(eq(true))
    }

    private fun verifyActionsDoNothing(keycode: Int) {
        // action down: does nothing
        val actionDownMenuKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, keycode)
        assertThat(underTest.dispatchKeyEvent(actionDownMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()
        verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())

        // action up: doesNothing
        val actionUpMenuKeyEvent = KeyEvent(KeyEvent.ACTION_UP, keycode)
        assertThat(underTest.dispatchKeyEvent(actionUpMenuKeyEvent)).isFalse()
        verify(shadeController, never()).animateCollapseShadeForced()
        verify(statusBarKeyguardViewManager, never()).showPrimaryBouncer(any())
    }
}