1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.keyguard 18 19 import android.annotation.CurrentTimeMillisLong 20 import com.android.systemui.common.buffer.RingBuffer 21 import com.android.systemui.dump.DumpsysTableLogger 22 import com.android.systemui.dump.Row 23 24 /** Verbose debug information associated. */ 25 data class KeyguardFaceListenModel( 26 @CurrentTimeMillisLong override var timeMillis: Long = 0L, 27 override var userId: Int = 0, 28 override var listening: Boolean = false, 29 // keep sorted 30 var allowedDisplayStateWhileAwake: Boolean = false, 31 var alternateBouncerShowing: Boolean = false, 32 var authInterruptActive: Boolean = false, 33 var biometricSettingEnabledForUser: Boolean = false, 34 var bouncerFullyShown: Boolean = false, 35 var faceAndFpNotAuthenticated: Boolean = false, 36 var faceAuthAllowed: Boolean = false, 37 var faceDisabled: Boolean = false, 38 var faceLockedOut: Boolean = false, 39 var goingToSleep: Boolean = false, 40 var keyguardAwake: Boolean = false, 41 var keyguardGoingAway: Boolean = false, 42 var listeningForFaceAssistant: Boolean = false, 43 var occludingAppRequestingFaceAuth: Boolean = false, 44 var postureAllowsListening: Boolean = false, 45 var secureCameraLaunched: Boolean = false, 46 var supportsDetect: Boolean = false, 47 var switchingUser: Boolean = false, 48 var systemUser: Boolean = false, 49 var udfpsFingerDown: Boolean = false, 50 var userNotTrustedOrDetectionIsNeeded: Boolean = false, 51 ) : KeyguardListenModel() { 52 53 /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */ 54 val asStringList: List<String> by lazy { 55 listOf( 56 DATE_FORMAT.format(timeMillis), 57 timeMillis.toString(), 58 userId.toString(), 59 listening.toString(), 60 // keep sorted 61 allowedDisplayStateWhileAwake.toString(), 62 alternateBouncerShowing.toString(), 63 authInterruptActive.toString(), 64 biometricSettingEnabledForUser.toString(), 65 bouncerFullyShown.toString(), 66 faceAndFpNotAuthenticated.toString(), 67 faceAuthAllowed.toString(), 68 faceDisabled.toString(), 69 faceLockedOut.toString(), 70 goingToSleep.toString(), 71 keyguardAwake.toString(), 72 keyguardGoingAway.toString(), 73 listeningForFaceAssistant.toString(), 74 occludingAppRequestingFaceAuth.toString(), 75 postureAllowsListening.toString(), 76 secureCameraLaunched.toString(), 77 supportsDetect.toString(), 78 switchingUser.toString(), 79 systemUser.toString(), 80 udfpsFingerDown.toString(), 81 userNotTrustedOrDetectionIsNeeded.toString(), 82 ) 83 } 84 85 /** 86 * [RingBuffer] to store [KeyguardFaceListenModel]. After the buffer is full, it will recycle 87 * old events. 88 * 89 * Do not use [append] to add new elements. Instead use [insert], as it will recycle if 90 * necessary. 91 */ 92 class Buffer { 93 private val buffer = RingBuffer(CAPACITY) { KeyguardFaceListenModel() } 94 95 fun insert(model: KeyguardFaceListenModel) { 96 buffer.advance().apply { 97 timeMillis = model.timeMillis 98 userId = model.userId 99 listening = model.listening 100 // keep sorted 101 allowedDisplayStateWhileAwake = model.allowedDisplayStateWhileAwake 102 alternateBouncerShowing = model.alternateBouncerShowing 103 authInterruptActive = model.authInterruptActive 104 biometricSettingEnabledForUser = model.biometricSettingEnabledForUser 105 bouncerFullyShown = model.bouncerFullyShown 106 faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated 107 faceAuthAllowed = model.faceAuthAllowed 108 faceDisabled = model.faceDisabled 109 faceLockedOut = model.faceLockedOut 110 goingToSleep = model.goingToSleep 111 keyguardAwake = model.keyguardAwake 112 keyguardGoingAway = model.keyguardGoingAway 113 listeningForFaceAssistant = model.listeningForFaceAssistant 114 occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth 115 postureAllowsListening = model.postureAllowsListening 116 secureCameraLaunched = model.secureCameraLaunched 117 supportsDetect = model.supportsDetect 118 switchingUser = model.switchingUser 119 systemUser = model.systemUser 120 udfpsFingerDown = model.udfpsFingerDown 121 userNotTrustedOrDetectionIsNeeded = model.userNotTrustedOrDetectionIsNeeded 122 } 123 } 124 /** 125 * Returns the content of the buffer (sorted from latest to newest). 126 * 127 * @see KeyguardFingerprintListenModel.asStringList 128 */ 129 fun toList(): List<Row> { 130 return buffer.asSequence().map { it.asStringList }.toList() 131 } 132 } 133 134 companion object { 135 const val CAPACITY = 40 // number of logs to retain 136 137 /** Headers for dumping a table using [DumpsysTableLogger]. */ 138 @JvmField 139 val TABLE_HEADERS = 140 listOf( 141 "timestamp", 142 "time_millis", 143 "userId", 144 "listening", 145 // keep sorted 146 "allowedDisplayStateWhileAwake", 147 "alternateBouncerShowing", 148 "authInterruptActive", 149 "biometricSettingEnabledForUser", 150 "bouncerFullyShown", 151 "faceAndFpNotAuthenticated", 152 "faceAuthAllowed", 153 "faceDisabled", 154 "faceLockedOut", 155 "goingToSleep", 156 "keyguardAwake", 157 "keyguardGoingAway", 158 "listeningForFaceAssistant", 159 "occludingAppRequestingFaceAuth", 160 "postureAllowsListening", 161 "secureCameraLaunched", 162 "supportsDetect", 163 "switchingUser", 164 "systemUser", 165 "udfpsFingerDown", 166 "userNotTrustedOrDetectionIsNeeded", 167 ) 168 } 169 } 170