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

Commit d8aadbd7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Replace KeyguardListenQueue with DumpsysTableLogger" into tm-qpr-dev

parents 8a83f07a eabef8f3
Loading
Loading
Loading
Loading
+114 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.keyguard

import android.annotation.CurrentTimeMillisLong
import com.android.systemui.dump.DumpsysTableLogger
import com.android.systemui.dump.Row
import com.android.systemui.plugins.util.RingBuffer

/** Verbose debug information. */
data class KeyguardActiveUnlockModel(
    @CurrentTimeMillisLong override var timeMillis: Long = 0L,
    override var userId: Int = 0,
    override var listening: Boolean = false,
    // keep sorted
    var awakeKeyguard: Boolean = false,
    var authInterruptActive: Boolean = false,
    var fpLockedOut: Boolean = false,
    var primaryAuthRequired: Boolean = false,
    var switchingUser: Boolean = false,
    var triggerActiveUnlockForAssistant: Boolean = false,
    var userCanDismissLockScreen: Boolean = false,
) : KeyguardListenModel() {

    /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
    val asStringList: List<String> by lazy {
        listOf(
            DATE_FORMAT.format(timeMillis),
            timeMillis.toString(),
            userId.toString(),
            listening.toString(),
            // keep sorted
            awakeKeyguard.toString(),
            authInterruptActive.toString(),
            fpLockedOut.toString(),
            primaryAuthRequired.toString(),
            switchingUser.toString(),
            triggerActiveUnlockForAssistant.toString(),
            userCanDismissLockScreen.toString(),
        )
    }

    /**
     * [RingBuffer] to store [KeyguardActiveUnlockModel]. After the buffer is full, it will recycle
     * old events.
     *
     * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
     * necessary.
     */
    class Buffer {
        private val buffer = RingBuffer(CAPACITY) { KeyguardActiveUnlockModel() }

        fun insert(model: KeyguardActiveUnlockModel) {
            buffer.advance().apply {
                timeMillis = model.timeMillis
                userId = model.userId
                listening = model.listening
                // keep sorted
                awakeKeyguard = model.awakeKeyguard
                authInterruptActive = model.authInterruptActive
                fpLockedOut = model.fpLockedOut
                primaryAuthRequired = model.primaryAuthRequired
                switchingUser = model.switchingUser
                triggerActiveUnlockForAssistant = model.triggerActiveUnlockForAssistant
                userCanDismissLockScreen = model.userCanDismissLockScreen
            }
        }

        /**
         * Returns the content of the buffer (sorted from latest to newest).
         *
         * @see KeyguardFingerprintListenModel.asStringList
         */
        fun toList(): List<Row> {
            return buffer.asSequence().map { it.asStringList }.toList()
        }
    }

    companion object {
        const val CAPACITY = 20 // number of logs to retain

        /** Headers for dumping a table using [DumpsysTableLogger]. */
        @JvmField
        val TABLE_HEADERS =
            listOf(
                "timestamp",
                "time_millis",
                "userId",
                "listening",
                // keep sorted
                "awakeKeyguard",
                "authInterruptActive",
                "fpLockedOut",
                "primaryAuthRequired",
                "switchingUser",
                "triggerActiveUnlockForAssistant",
                "userCanDismissLockScreen",
            )
    }
}
+162 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.keyguard

import android.annotation.CurrentTimeMillisLong
import com.android.systemui.dump.DumpsysTableLogger
import com.android.systemui.dump.Row
import com.android.systemui.plugins.util.RingBuffer

/** Verbose debug information associated. */
data class KeyguardFaceListenModel(
    @CurrentTimeMillisLong override var timeMillis: Long = 0L,
    override var userId: Int = 0,
    override var listening: Boolean = false,
    // keep sorted
    var authInterruptActive: Boolean = false,
    var biometricSettingEnabledForUser: Boolean = false,
    var bouncerFullyShown: Boolean = false,
    var faceAndFpNotAuthenticated: Boolean = false,
    var faceAuthAllowed: Boolean = false,
    var faceDisabled: Boolean = false,
    var faceLockedOut: Boolean = false,
    var goingToSleep: Boolean = false,
    var keyguardAwake: Boolean = false,
    var keyguardGoingAway: Boolean = false,
    var listeningForFaceAssistant: Boolean = false,
    var occludingAppRequestingFaceAuth: Boolean = false,
    var primaryUser: Boolean = false,
    var secureCameraLaunched: Boolean = false,
    var supportsDetect: Boolean = false,
    var switchingUser: Boolean = false,
    var udfpsBouncerShowing: Boolean = false,
    var udfpsFingerDown: Boolean = false,
    var userNotTrustedOrDetectionIsNeeded: Boolean = false,
) : KeyguardListenModel() {

    /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
    val asStringList: List<String> by lazy {
        listOf(
            DATE_FORMAT.format(timeMillis),
            timeMillis.toString(),
            userId.toString(),
            listening.toString(),
            // keep sorted
            authInterruptActive.toString(),
            biometricSettingEnabledForUser.toString(),
            bouncerFullyShown.toString(),
            faceAndFpNotAuthenticated.toString(),
            faceAuthAllowed.toString(),
            faceDisabled.toString(),
            faceLockedOut.toString(),
            goingToSleep.toString(),
            keyguardAwake.toString(),
            keyguardGoingAway.toString(),
            listeningForFaceAssistant.toString(),
            occludingAppRequestingFaceAuth.toString(),
            primaryUser.toString(),
            secureCameraLaunched.toString(),
            supportsDetect.toString(),
            switchingUser.toString(),
            udfpsBouncerShowing.toString(),
            udfpsFingerDown.toString(),
            userNotTrustedOrDetectionIsNeeded.toString(),
        )
    }

    /**
     * [RingBuffer] to store [KeyguardFaceListenModel]. After the buffer is full, it will recycle
     * old events.
     *
     * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
     * necessary.
     */
    class Buffer {
        private val buffer = RingBuffer(CAPACITY) { KeyguardFaceListenModel() }

        fun insert(model: KeyguardFaceListenModel) {
            buffer.advance().apply {
                timeMillis = model.timeMillis
                userId = model.userId
                listening = model.listening
                // keep sorted
                biometricSettingEnabledForUser = model.biometricSettingEnabledForUser
                bouncerFullyShown = model.bouncerFullyShown
                faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated
                faceAuthAllowed = model.faceAuthAllowed
                faceDisabled = model.faceDisabled
                faceLockedOut = model.faceLockedOut
                goingToSleep = model.goingToSleep
                keyguardAwake = model.keyguardAwake
                goingToSleep = model.goingToSleep
                keyguardGoingAway = model.keyguardGoingAway
                listeningForFaceAssistant = model.listeningForFaceAssistant
                occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth
                primaryUser = model.primaryUser
                secureCameraLaunched = model.secureCameraLaunched
                supportsDetect = model.supportsDetect
                switchingUser = model.switchingUser
                udfpsBouncerShowing = model.udfpsBouncerShowing
                switchingUser = model.switchingUser
                udfpsFingerDown = model.udfpsFingerDown
                userNotTrustedOrDetectionIsNeeded = model.userNotTrustedOrDetectionIsNeeded
            }
        }
        /**
         * Returns the content of the buffer (sorted from latest to newest).
         *
         * @see KeyguardFingerprintListenModel.asStringList
         */
        fun toList(): List<Row> {
            return buffer.asSequence().map { it.asStringList }.toList()
        }
    }

    companion object {
        const val CAPACITY = 40 // number of logs to retain

        /** Headers for dumping a table using [DumpsysTableLogger]. */
        @JvmField
        val TABLE_HEADERS =
            listOf(
                "timestamp",
                "time_millis",
                "userId",
                "listening",
                // keep sorted
                "authInterruptActive",
                "biometricSettingEnabledForUser",
                "bouncerFullyShown",
                "faceAndFpNotAuthenticated",
                "faceAuthAllowed",
                "faceDisabled",
                "faceLockedOut",
                "goingToSleep",
                "keyguardAwake",
                "keyguardGoingAway",
                "listeningForFaceAssistant",
                "occludingAppRequestingFaceAuth",
                "primaryUser",
                "secureCameraLaunched",
                "supportsDetect",
                "switchingUser",
                "udfpsBouncerShowing",
                "udfpsFingerDown",
                "userNotTrustedOrDetectionIsNeeded",
            )
    }
}
+166 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.keyguard

import android.annotation.CurrentTimeMillisLong
import com.android.systemui.dump.DumpsysTableLogger
import com.android.systemui.dump.Row
import com.android.systemui.plugins.util.RingBuffer

/** Verbose debug information. */
data class KeyguardFingerprintListenModel(
    @CurrentTimeMillisLong override var timeMillis: Long = 0L,
    override var userId: Int = 0,
    override var listening: Boolean = false,
    // keepSorted
    var biometricEnabledForUser: Boolean = false,
    var bouncerIsOrWillShow: Boolean = false,
    var canSkipBouncer: Boolean = false,
    var credentialAttempted: Boolean = false,
    var deviceInteractive: Boolean = false,
    var dreaming: Boolean = false,
    var fingerprintDisabled: Boolean = false,
    var fingerprintLockedOut: Boolean = false,
    var goingToSleep: Boolean = false,
    var keyguardGoingAway: Boolean = false,
    var keyguardIsVisible: Boolean = false,
    var keyguardOccluded: Boolean = false,
    var occludingAppRequestingFp: Boolean = false,
    var primaryUser: Boolean = false,
    var shouldListenSfpsState: Boolean = false,
    var shouldListenForFingerprintAssistant: Boolean = false,
    var strongerAuthRequired: Boolean = false,
    var switchingUser: Boolean = false,
    var udfps: Boolean = false,
    var userDoesNotHaveTrust: Boolean = false,
) : KeyguardListenModel() {

    /** List of [String] to be used as a [Row] with [DumpsysTableLogger]. */
    val asStringList: List<String> by lazy {
        listOf(
            DATE_FORMAT.format(timeMillis),
            timeMillis.toString(),
            userId.toString(),
            listening.toString(),
            // keep sorted
            biometricEnabledForUser.toString(),
            bouncerIsOrWillShow.toString(),
            canSkipBouncer.toString(),
            credentialAttempted.toString(),
            deviceInteractive.toString(),
            dreaming.toString(),
            fingerprintDisabled.toString(),
            fingerprintLockedOut.toString(),
            goingToSleep.toString(),
            keyguardGoingAway.toString(),
            keyguardIsVisible.toString(),
            keyguardOccluded.toString(),
            occludingAppRequestingFp.toString(),
            primaryUser.toString(),
            shouldListenSfpsState.toString(),
            shouldListenForFingerprintAssistant.toString(),
            strongerAuthRequired.toString(),
            switchingUser.toString(),
            udfps.toString(),
            userDoesNotHaveTrust.toString(),
        )
    }

    /**
     * [RingBuffer] to store [KeyguardFingerprintListenModel]. After the buffer is full, it will
     * recycle old events.
     *
     * Do not use [append] to add new elements. Instead use [insert], as it will recycle if
     * necessary.
     */
    class Buffer {
        private val buffer = RingBuffer(CAPACITY) { KeyguardFingerprintListenModel() }

        fun insert(model: KeyguardFingerprintListenModel) {
            buffer.advance().apply {
                timeMillis = model.timeMillis
                userId = model.userId
                listening = model.listening
                // keep sorted
                biometricEnabledForUser = model.biometricEnabledForUser
                bouncerIsOrWillShow = model.bouncerIsOrWillShow
                canSkipBouncer = model.canSkipBouncer
                credentialAttempted = model.credentialAttempted
                deviceInteractive = model.deviceInteractive
                dreaming = model.dreaming
                fingerprintDisabled = model.fingerprintDisabled
                fingerprintLockedOut = model.fingerprintLockedOut
                goingToSleep = model.goingToSleep
                keyguardGoingAway = model.keyguardGoingAway
                keyguardIsVisible = model.keyguardIsVisible
                keyguardOccluded = model.keyguardOccluded
                occludingAppRequestingFp = model.occludingAppRequestingFp
                primaryUser = model.primaryUser
                shouldListenSfpsState = model.shouldListenSfpsState
                shouldListenForFingerprintAssistant = model.shouldListenForFingerprintAssistant
                strongerAuthRequired = model.strongerAuthRequired
                switchingUser = model.switchingUser
                udfps = model.udfps
                userDoesNotHaveTrust = model.userDoesNotHaveTrust
            }
        }

        /**
         * Returns the content of the buffer (sorted from latest to newest).
         *
         * @see KeyguardFingerprintListenModel.asStringList
         */
        fun toList(): List<Row> {
            return buffer.asSequence().map { it.asStringList }.toList()
        }
    }

    companion object {
        const val CAPACITY = 20 // number of logs to retain

        /** Headers for dumping a table using [DumpsysTableLogger]. */
        @JvmField
        val TABLE_HEADERS =
            listOf(
                "timestamp",
                "time_millis",
                "userId",
                "listening",
                // keep sorted
                "biometricAllowedForUser",
                "bouncerIsOrWillShow",
                "canSkipBouncer",
                "credentialAttempted",
                "deviceInteractive",
                "dreaming",
                "fingerprintDisabled",
                "fingerprintLockedOut",
                "goingToSleep",
                "keyguardGoingAway",
                "keyguardIsVisible",
                "keyguardOccluded",
                "occludingAppRequestingFp",
                "primaryUser",
                "shouldListenSidFingerprintState",
                "shouldListenForFingerprintAssistant",
                "strongAuthRequired",
                "switchingUser",
                "underDisplayFingerprint",
                "userDoesNotHaveTrust",
            )
    }
}
+22 −77
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.keyguard

import android.annotation.CurrentTimeMillisLong
import java.text.SimpleDateFormat
import java.util.Locale

/** Verbose logging for various keyguard listening states. */
sealed class KeyguardListenModel {
    /** Timestamp of the state change. */
    abstract val timeMillis: Long
    abstract var timeMillis: Long
    /** Current user. */
    abstract val userId: Int
    abstract var userId: Int
    /** If keyguard is listening for the modality represented by this model. */
    abstract val listening: Boolean
    abstract var listening: Boolean
}

/**
 * Verbose debug information associated with [KeyguardUpdateMonitor.shouldListenForFingerprint].
 */
data class KeyguardFingerprintListenModel(
    @CurrentTimeMillisLong override val timeMillis: Long,
    override val userId: Int,
    override val listening: Boolean,
    // keep sorted
    val biometricEnabledForUser: Boolean,
    val bouncerIsOrWillShow: Boolean,
    val canSkipBouncer: Boolean,
    val credentialAttempted: Boolean,
    val deviceInteractive: Boolean,
    val dreaming: Boolean,
    val fingerprintDisabled: Boolean,
    val fingerprintLockedOut: Boolean,
    val goingToSleep: Boolean,
    val keyguardGoingAway: Boolean,
    val keyguardIsVisible: Boolean,
    val keyguardOccluded: Boolean,
    val occludingAppRequestingFp: Boolean,
    val primaryUser: Boolean,
    val shouldListenSfpsState: Boolean,
    val shouldListenForFingerprintAssistant: Boolean,
    val strongerAuthRequired: Boolean,
    val switchingUser: Boolean,
    val udfps: Boolean,
    val userDoesNotHaveTrust: Boolean
) : KeyguardListenModel()
/**
 * Verbose debug information associated with [KeyguardUpdateMonitor.shouldListenForFace].
 */
data class KeyguardFaceListenModel(
    @CurrentTimeMillisLong override val timeMillis: Long,
    override val userId: Int,
    override val listening: Boolean,
    // keep sorted
    val authInterruptActive: Boolean,
    val biometricSettingEnabledForUser: Boolean,
    val bouncerFullyShown: Boolean,
    val faceAndFpNotAuthenticated: Boolean,
    val faceAuthAllowed: Boolean,
    val faceDisabled: Boolean,
    val faceLockedOut: Boolean,
    val goingToSleep: Boolean,
    val keyguardAwake: Boolean,
    val keyguardGoingAway: Boolean,
    val listeningForFaceAssistant: Boolean,
    val occludingAppRequestingFaceAuth: Boolean,
    val primaryUser: Boolean,
    val secureCameraLaunched: Boolean,
    val supportsDetect: Boolean,
    val switchingUser: Boolean,
    val udfpsBouncerShowing: Boolean,
    val udfpsFingerDown: Boolean,
    val userNotTrustedOrDetectionIsNeeded: Boolean,
    ) : KeyguardListenModel()
/**
 * Verbose debug information associated with [KeyguardUpdateMonitor.shouldTriggerActiveUnlock].
 */
data class KeyguardActiveUnlockModel(
    @CurrentTimeMillisLong override val timeMillis: Long,
    override val userId: Int,
    override val listening: Boolean,
    // keep sorted
    val awakeKeyguard: Boolean,
    val authInterruptActive: Boolean,
    val fpLockedOut: Boolean,
    val primaryAuthRequired: Boolean,
    val switchingUser: Boolean,
    val triggerActiveUnlockForAssistant: Boolean,
    val userCanDismissLockScreen: Boolean
) : KeyguardListenModel()
val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
+0 −73
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.keyguard

import androidx.annotation.VisibleForTesting
import java.io.PrintWriter
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.collections.ArrayDeque

private val DEFAULT_FORMATTING = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)

/** Queue for verbose logging checks for the listening state. */
class KeyguardListenQueue(
    val sizePerModality: Int = 20
) {
    private val faceQueue = ArrayDeque<KeyguardFaceListenModel>()
    private val fingerprintQueue = ArrayDeque<KeyguardFingerprintListenModel>()
    private val activeUnlockQueue = ArrayDeque<KeyguardActiveUnlockModel>()

    @get:VisibleForTesting val models: List<KeyguardListenModel>
        get() = faceQueue + fingerprintQueue + activeUnlockQueue

    /** Push a [model] to the queue (will be logged until the queue exceeds [sizePerModality]). */
    fun add(model: KeyguardListenModel) {
        val queue = when (model) {
            is KeyguardFaceListenModel -> faceQueue.apply { add(model) }
            is KeyguardFingerprintListenModel -> fingerprintQueue.apply { add(model) }
            is KeyguardActiveUnlockModel -> activeUnlockQueue.apply { add(model) }
        }

        if (queue.size > sizePerModality) {
            queue.removeFirstOrNull()
        }
    }

    /** Print verbose logs via the [writer]. */
    @JvmOverloads
    fun print(writer: PrintWriter, dateFormat: DateFormat = DEFAULT_FORMATTING) {
        val stringify: (KeyguardListenModel) -> String = { model ->
            "    ${dateFormat.format(Date(model.timeMillis))} $model"
        }

        writer.println("  Face listen results (last ${faceQueue.size} calls):")
        for (model in faceQueue) {
            writer.println(stringify(model))
        }
        writer.println("  Fingerprint listen results (last ${fingerprintQueue.size} calls):")
        for (model in fingerprintQueue) {
            writer.println(stringify(model))
        }
        writer.println("  Active unlock triggers (last ${activeUnlockQueue.size} calls):")
        for (model in activeUnlockQueue) {
            writer.println(stringify(model))
        }
    }
}
Loading