Loading packages/SystemUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -2563,6 +2563,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> Loading packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt +7 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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." } } Loading Loading @@ -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 Loading @@ -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]. */ Loading packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +4 −1 Original line number Diff line number Diff line Loading @@ -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.classifier.FalsingA11yDelegate; Loading Loading @@ -385,9 +386,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard TelephonyManager telephonyManager, ViewMediatorCallback viewMediatorCallback, AudioManager audioManager, KeyguardFaceAuthInteractor keyguardFaceAuthInteractor KeyguardFaceAuthInteractor keyguardFaceAuthInteractor, FaceAuthAccessibilityDelegate faceAuthAccessibilityDelegate ) { super(view); view.setAccessibilityDelegate(faceAuthAccessibilityDelegate); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = keyguardUpdateMonitor; mSecurityModel = keyguardSecurityModel; Loading packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +4 −0 Original line number Diff line number Diff line Loading @@ -3136,6 +3136,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; Loading packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt 0 → 100644 +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
packages/SystemUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -2563,6 +2563,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> Loading
packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt +7 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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." } } Loading Loading @@ -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 Loading @@ -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]. */ Loading
packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +4 −1 Original line number Diff line number Diff line Loading @@ -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.classifier.FalsingA11yDelegate; Loading Loading @@ -385,9 +386,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard TelephonyManager telephonyManager, ViewMediatorCallback viewMediatorCallback, AudioManager audioManager, KeyguardFaceAuthInteractor keyguardFaceAuthInteractor KeyguardFaceAuthInteractor keyguardFaceAuthInteractor, FaceAuthAccessibilityDelegate faceAuthAccessibilityDelegate ) { super(view); view.setAccessibilityDelegate(faceAuthAccessibilityDelegate); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = keyguardUpdateMonitor; mSecurityModel = keyguardSecurityModel; Loading
packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +4 −0 Original line number Diff line number Diff line Loading @@ -3136,6 +3136,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; Loading
packages/SystemUI/src/com/android/systemui/biometrics/FaceAuthAccessibilityDelegate.kt 0 → 100644 +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) } }