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