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

Commit 4a0a2add authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

Add face auth a11y action to bouncer view

Test: atest FaceAuthAccessibilityDelegateTest KeyguardSecurityContainerControllerTest
Test: manually enable switch access and see user
has a way to retrigger face auth using switch access
(tested with and without new face auth refactor)
Bug: 289162753

Change-Id: I42a77f815ec90dab60a3c585a63993e2e1e579d9
parent 3c0f4149
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2582,6 +2582,9 @@
    <!-- Tooltip to show in management screen when there are multiple structures [CHAR_LIMIT=50] -->
    <string name="controls_structure_tooltip">Swipe to see more</string>

    <!-- Accessibility action informing the user how they can retry face authentication [CHAR LIMIT=NONE] -->
    <string name="retry_face">Retry face authentication</string>

    <!-- Message to tell the user to wait while systemui attempts to load a set of
         recommended controls [CHAR_LIMIT=60] -->
    <string name="controls_seeding_in_progress">Loading recommendations</string>
+7 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.StringDef
import android.os.PowerManager
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.keyguard.FaceAuthApiRequestReason.Companion.ACCESSIBILITY_ACTION
import com.android.keyguard.FaceAuthApiRequestReason.Companion.NOTIFICATION_PANEL_CLICKED
import com.android.keyguard.FaceAuthApiRequestReason.Companion.PICK_UP_GESTURE_TRIGGERED
import com.android.keyguard.FaceAuthApiRequestReason.Companion.QS_EXPANDED
@@ -71,6 +72,7 @@ import com.android.keyguard.InternalFaceAuthReasons.USER_SWITCHING
    NOTIFICATION_PANEL_CLICKED,
    QS_EXPANDED,
    PICK_UP_GESTURE_TRIGGERED,
    ACCESSIBILITY_ACTION,
)
annotation class FaceAuthApiRequestReason {
    companion object {
@@ -80,6 +82,7 @@ annotation class FaceAuthApiRequestReason {
        const val QS_EXPANDED = "Face auth due to QS expansion."
        const val PICK_UP_GESTURE_TRIGGERED =
            "Face auth due to pickup gesture triggered when the device is awake and not from AOD."
        const val ACCESSIBILITY_ACTION = "Face auth due to an accessibility action."
    }
}

@@ -217,7 +220,8 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
    @UiEvent(doc = STRONG_AUTH_ALLOWED_CHANGED)
    FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED(1255, STRONG_AUTH_ALLOWED_CHANGED),
    @UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
    FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED);
    FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED),
    @UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION);

    override fun getId(): Int = this.id

@@ -233,6 +237,8 @@ private val apiRequestReasonToUiEvent =
            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED,
        QS_EXPANDED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED,
        PICK_UP_GESTURE_TRIGGERED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED,
        PICK_UP_GESTURE_TRIGGERED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED,
        ACCESSIBILITY_ACTION to FaceAuthUiEvent.FACE_AUTH_ACCESSIBILITY_ACTION,
    )

/** Converts the [reason] to the corresponding [FaceAuthUiEvent]. */
+3 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import com.android.keyguard.dagger.KeyguardBouncerScope;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
import com.android.systemui.biometrics.FaceAuthAccessibilityDelegate;
import com.android.systemui.biometrics.SideFpsController;
import com.android.systemui.biometrics.SideFpsUiRequestSource;
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
@@ -417,9 +418,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            BouncerMessageInteractor bouncerMessageInteractor,
            Provider<JavaAdapter> javaAdapter,
            UserInteractor userInteractor,
            FaceAuthAccessibilityDelegate faceAuthAccessibilityDelegate,
            Provider<SceneInteractor> sceneInteractor
    ) {
        super(view);
        view.setAccessibilityDelegate(faceAuthAccessibilityDelegate);
        mLockPatternUtils = lockPatternUtils;
        mUpdateMonitor = keyguardUpdateMonitor;
        mSecurityModel = keyguardSecurityModel;
+4 −0
Original line number Diff line number Diff line
@@ -3158,6 +3158,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            return false;
        }

        if (isFaceAuthInteractorEnabled()) {
            return mFaceAuthInteractor.canFaceAuthRun();
        }

        final boolean statusBarShadeLocked = mStatusBarState == StatusBarState.SHADE_LOCKED;
        final boolean awakeKeyguard = isKeyguardVisible() && mDeviceInteractive
                && !statusBarShadeLocked;
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.biometrics

import android.content.res.Resources
import android.os.Bundle
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo
import com.android.keyguard.FaceAuthApiRequestReason
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor
import javax.inject.Inject

/**
 * Accessibility delegate that will add a click accessibility action to a view when face auth can
 * run. When the click a11y action is triggered, face auth will retry.
 */
@SysUISingleton
class FaceAuthAccessibilityDelegate
@Inject
constructor(
    @Main private val resources: Resources,
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    private val faceAuthInteractor: KeyguardFaceAuthInteractor,
) : View.AccessibilityDelegate() {
    override fun onInitializeAccessibilityNodeInfo(host: View?, info: AccessibilityNodeInfo) {
        super.onInitializeAccessibilityNodeInfo(host, info)
        if (keyguardUpdateMonitor.shouldListenForFace()) {
            val clickActionToRetryFace =
                AccessibilityNodeInfo.AccessibilityAction(
                    AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id,
                    resources.getString(R.string.retry_face)
                )
            info.addAction(clickActionToRetryFace)
        }
    }

    override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
        return if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id) {
            keyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.ACCESSIBILITY_ACTION)
            faceAuthInteractor.onAccessibilityAction()
            true
        } else super.performAccessibilityAction(host, action, args)
    }
}
Loading