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.dump.DumpsysTableLogger 21 import com.android.systemui.dump.Row 22 import com.android.systemui.plugins.util.RingBuffer 23 24 /** Verbose debug information. */ 25 data class KeyguardFingerprintListenModel( 26 @CurrentTimeMillisLong override var timeMillis: Long = 0L, 27 override var userId: Int = 0, 28 override var listening: Boolean = false, 29 // keepSorted 30 var alternateBouncerShowing: Boolean = false, 31 var biometricEnabledForUser: Boolean = false, 32 var bouncerIsOrWillShow: Boolean = false, 33 var canSkipBouncer: Boolean = false, 34 var credentialAttempted: Boolean = false, 35 var deviceInteractive: Boolean = false, 36 var dreaming: Boolean = false, 37 var fingerprintDisabled: Boolean = false, 38 var fingerprintLockedOut: Boolean = false, 39 var goingToSleep: Boolean = false, 40 var keyguardGoingAway: Boolean = false, 41 var keyguardIsVisible: Boolean = false, 42 var keyguardOccluded: Boolean = false, 43 var occludingAppRequestingFp: Boolean = false, 44 var primaryUser: Boolean = false, 45 var shouldListenSfpsState: Boolean = false, 46 var shouldListenForFingerprintAssistant: Boolean = false, 47 var strongerAuthRequired: Boolean = false, 48 var switchingUser: Boolean = false, 49 var udfps: Boolean = false, 50 var userDoesNotHaveTrust: Boolean = false, 51 ) : KeyguardListenModel() { 52 53 /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */ <lambda>null54 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 alternateBouncerShowing.toString(), 62 biometricEnabledForUser.toString(), 63 bouncerIsOrWillShow.toString(), 64 canSkipBouncer.toString(), 65 credentialAttempted.toString(), 66 deviceInteractive.toString(), 67 dreaming.toString(), 68 fingerprintDisabled.toString(), 69 fingerprintLockedOut.toString(), 70 goingToSleep.toString(), 71 keyguardGoingAway.toString(), 72 keyguardIsVisible.toString(), 73 keyguardOccluded.toString(), 74 occludingAppRequestingFp.toString(), 75 primaryUser.toString(), 76 shouldListenSfpsState.toString(), 77 shouldListenForFingerprintAssistant.toString(), 78 strongerAuthRequired.toString(), 79 switchingUser.toString(), 80 udfps.toString(), 81 userDoesNotHaveTrust.toString(), 82 ) 83 } 84 85 /** 86 * [RingBuffer] to store [KeyguardFingerprintListenModel]. After the buffer is full, it will 87 * recycle 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 { <lambda>null93 private val buffer = RingBuffer(CAPACITY) { KeyguardFingerprintListenModel() } 94 insertnull95 fun insert(model: KeyguardFingerprintListenModel) { 96 buffer.advance().apply { 97 timeMillis = model.timeMillis 98 userId = model.userId 99 listening = model.listening 100 // keep sorted 101 alternateBouncerShowing = model.alternateBouncerShowing 102 biometricEnabledForUser = model.biometricEnabledForUser 103 bouncerIsOrWillShow = model.bouncerIsOrWillShow 104 canSkipBouncer = model.canSkipBouncer 105 credentialAttempted = model.credentialAttempted 106 deviceInteractive = model.deviceInteractive 107 dreaming = model.dreaming 108 fingerprintDisabled = model.fingerprintDisabled 109 fingerprintLockedOut = model.fingerprintLockedOut 110 goingToSleep = model.goingToSleep 111 keyguardGoingAway = model.keyguardGoingAway 112 keyguardIsVisible = model.keyguardIsVisible 113 keyguardOccluded = model.keyguardOccluded 114 occludingAppRequestingFp = model.occludingAppRequestingFp 115 primaryUser = model.primaryUser 116 shouldListenSfpsState = model.shouldListenSfpsState 117 shouldListenForFingerprintAssistant = model.shouldListenForFingerprintAssistant 118 strongerAuthRequired = model.strongerAuthRequired 119 switchingUser = model.switchingUser 120 udfps = model.udfps 121 userDoesNotHaveTrust = model.userDoesNotHaveTrust 122 } 123 } 124 125 /** 126 * Returns the content of the buffer (sorted from latest to newest). 127 * 128 * @see KeyguardFingerprintListenModel.asStringList 129 */ toListnull130 fun toList(): List<Row> { 131 return buffer.asSequence().map { it.asStringList }.toList() 132 } 133 } 134 135 companion object { 136 const val CAPACITY = 20 // number of logs to retain 137 138 /** Headers for dumping a table using [DumpsysTableLogger]. */ 139 @JvmField 140 val TABLE_HEADERS = 141 listOf( 142 "timestamp", 143 "time_millis", 144 "userId", 145 "listening", 146 // keep sorted 147 "alternateBouncerShowing", 148 "biometricAllowedForUser", 149 "bouncerIsOrWillShow", 150 "canSkipBouncer", 151 "credentialAttempted", 152 "deviceInteractive", 153 "dreaming", 154 "fingerprintDisabled", 155 "fingerprintLockedOut", 156 "goingToSleep", 157 "keyguardGoingAway", 158 "keyguardIsVisible", 159 "keyguardOccluded", 160 "occludingAppRequestingFp", 161 "primaryUser", 162 "shouldListenSidFingerprintState", 163 "shouldListenForFingerprintAssistant", 164 "strongAuthRequired", 165 "switchingUser", 166 "underDisplayFingerprint", 167 "userDoesNotHaveTrust", 168 ) 169 } 170 } 171