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

Commit 1a701cb8 authored by Brad Hinegardner's avatar Brad Hinegardner
Browse files

Customize lock screen button access via A11y tools

The ability to long-press on lockscreen was not available by Talkback or
Switch Access.

When the user triggers the "customize lock screen" from an A11y action
within the switch access popup or other tools, we should bypass the menu
from showing up and displaying, and instead go straight into the
auth->wallpaper picker flow.

Fixes: 318039541
Fixes: 318036479
Test: atest KeyguardTouchHandlingInteractorTest
Test: manual - activate Talkback on foldable and udfps devices
Test: manual - activate Switch Access on foldable and udfps devices
Flag: EXEMPT bugfix
Change-Id: I3ebfae00c21b80a35c6d642e8aaff0ab63494311
parent dc15b279
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ fun LockscreenLongPress(
            modifier
                .pointerInput(isEnabled) {
                    if (isEnabled) {
                        detectLongPressGesture { viewModel.onLongPress() }
                        detectLongPressGesture { viewModel.onLongPress(isA11yAction = false) }
                    }
                }
                .pointerInput(Unit) {
+15 −0
Original line number Diff line number Diff line
@@ -184,6 +184,21 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
            assertThat(shouldOpenSettings).isTrue()
        }

    @Test
    fun longPressed_isA11yAction_doesNotShowMenu_opensSettings() =
        testScope.runTest {
            createUnderTest(isOpenWppDirectlyEnabled = true)
            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
            val isA11yAction = true
            runCurrent()

            underTest.onLongPress(isA11yAction)

            assertThat(isMenuVisible).isFalse()
            assertThat(shouldOpenSettings).isTrue()
        }

    @Test
    fun longPressed_closeDialogsBroadcastReceived_popupDismissed() =
        testScope.runTest {
+56 −0
Original line number Diff line number Diff line
@@ -19,10 +19,14 @@ package com.android.systemui.common.ui.view

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.accessibility.AccessibilityNodeInfo
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import com.android.systemui.shade.TouchLogger
import kotlin.math.pow
import kotlin.math.sqrt
@@ -44,6 +48,10 @@ class LongPressHandlingView(
        attrs,
    ) {

    init {
        setupAccessibilityDelegate()
    }

    constructor(
        context: Context,
        attrs: AttributeSet?,
@@ -55,6 +63,7 @@ class LongPressHandlingView(
            view: View,
            x: Int,
            y: Int,
            isA11yAction: Boolean = false,
        )

        /** Notifies that the gesture was too short for a long press, it is actually a click. */
@@ -63,6 +72,8 @@ class LongPressHandlingView(

    var listener: Listener? = null

    var accessibilityHintLongPressAction: AccessibilityAction? = null

    private val interactionHandler: LongPressHandlingViewInteractionHandler by lazy {
        LongPressHandlingViewInteractionHandler(
            postDelayed = { block, timeoutMs ->
@@ -107,6 +118,51 @@ class LongPressHandlingView(
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return interactionHandler.onTouchEvent(event?.toModel())
    }

    private fun setupAccessibilityDelegate() {
        accessibilityDelegate =
            object : AccessibilityDelegate() {
                override fun onInitializeAccessibilityNodeInfo(
                    v: View,
                    info: AccessibilityNodeInfo
                ) {
                    super.onInitializeAccessibilityNodeInfo(v, info)
                    if (
                        interactionHandler.isLongPressHandlingEnabled &&
                            accessibilityHintLongPressAction != null
                    ) {
                        info.addAction(accessibilityHintLongPressAction)
                    }
                }

                override fun performAccessibilityAction(
                    host: View,
                    action: Int,
                    args: Bundle?
                ): Boolean {
                    return if (
                        interactionHandler.isLongPressHandlingEnabled &&
                            action == AccessibilityNodeInfoCompat.ACTION_LONG_CLICK
                    ) {
                        val longPressHandlingView = host as? LongPressHandlingView
                        if (longPressHandlingView != null) {
                            // the coordinates are not available as it is an a11y long press
                            listener?.onLongPressDetected(
                                view = longPressHandlingView,
                                x = 0,
                                y = 0,
                                isA11yAction = true,
                            )
                            true
                        } else {
                            false
                        }
                    } else {
                        super.performAccessibilityAction(host, action, args)
                    }
                }
            }
    }
}

private fun MotionEvent.toModel(): LongPressHandlingViewInteractionHandler.MotionEventModel {
+6 −3
Original line number Diff line number Diff line
@@ -129,13 +129,16 @@ constructor(
        }
    }

    /** Notifies that the user has long-pressed on the lock screen. */
    fun onLongPress() {
    /** Notifies that the user has long-pressed on the lock screen.
     *
     * @param isA11yAction: Whether the action was performed as an a11y action
     */
    fun onLongPress(isA11yAction: Boolean = false) {
        if (!isLongPressHandlingEnabled.value) {
            return
        }

        if (featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP)) {
        if (isA11yAction || featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP)) {
            showSettings()
        } else {
            showMenu()
+2 −2
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ object DeviceEntryIconViewBinder {
        val bgView = view.bgView
        longPressHandlingView.listener =
            object : LongPressHandlingView.Listener {
                override fun onLongPressDetected(view: View, x: Int, y: Int) {
                    if (falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) {
                override fun onLongPressDetected(view: View, x: Int, y: Int, isA11yAction: Boolean) {
                    if (!isA11yAction && falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) {
                        return
                    }
                    vibratorHelper.performHapticFeedback(
Loading