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

Commit eb443786 authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Move face auth related computations to the background

It seems in many places flows were being flowed on the main thread just because the initial registration needed to happen in the main thread. for a couple of places.

This cl makes the combination of flow value happen in the bg thread, while the registration of listeners still happens in the ui thread (just to minimize changes: it would also be possible to change classes to make them thread safe)

This avoids a roughly 30ms of main thread work at every device state change.

Flag: None
Bug: 312894757
Test: DeviceEntryFingerprintAuthRepositoryTest, DevicePostureRepositoryTest + perfetto
Change-Id: If21b2622cf01ffd62c57a5162c65211940c0be72
parent 73330b61
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ constructor(
                    Pair(isAuthenticated.isFalse(), "faceNotAuthenticated"),
                )
                .andAllFlows("canFaceAuthRun", faceAuthLog)
                .flowOn(mainDispatcher)
                .flowOn(backgroundDispatcher)
                .stateIn(applicationScope, SharingStarted.Eagerly, false)

        // Face detection can run only when lockscreen bypass is enabled
@@ -280,7 +280,7 @@ constructor(
                    )
                )
                .andAllFlows("canFaceDetectRun", faceDetectLog)
                .flowOn(mainDispatcher)
                .flowOn(backgroundDispatcher)
                .stateIn(applicationScope, SharingStarted.Eagerly, false)
        observeFaceAuthGatingChecks()
        observeFaceDetectGatingChecks()
+30 −23
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
@@ -33,11 +34,13 @@ import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatu
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn

/** Encapsulates state about device entry fingerprint auth mechanism. */
@@ -74,6 +77,7 @@ constructor(
    val authController: AuthController,
    val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    @Application scope: CoroutineScope,
    @Main private val mainDispatcher: CoroutineDispatcher,
) : DeviceEntryFingerprintAuthRepository {

    override val availableFpSensorType: Flow<BiometricType?>
@@ -137,7 +141,8 @@ constructor(
            .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)

    override val isRunning: Flow<Boolean>
        get() = conflatedCallbackFlow {
        get() =
            conflatedCallbackFlow {
                    val callback =
                        object : KeyguardUpdateMonitorCallback() {
                            override fun onBiometricRunningStateChanged(
@@ -161,6 +166,9 @@ constructor(
                    )
                    awaitClose { keyguardUpdateMonitor.removeCallback(callback) }
                }
                .flowOn(
                    mainDispatcher
                ) // keyguardUpdateMonitor requires registration on main thread.

    override val authenticationStatus: Flow<FingerprintAuthenticationStatus>
        get() = conflatedCallbackFlow {
@@ -171,7 +179,6 @@ constructor(
                        biometricSourceType: BiometricSourceType,
                        isStrongBiometric: Boolean,
                    ) {

                        sendUpdateIfFingerprint(
                            biometricSourceType,
                            SuccessFingerprintAuthenticationStatus(
+23 −15
Original line number Diff line number Diff line
@@ -19,11 +19,14 @@ package com.android.systemui.keyguard.data.repository
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.shared.model.DevicePosture
import com.android.systemui.statusbar.policy.DevicePostureController
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn

/** Provide current device posture state. */
interface DevicePostureRepository {
@@ -34,9 +37,13 @@ interface DevicePostureRepository {
@SysUISingleton
class DevicePostureRepositoryImpl
@Inject
constructor(private val postureController: DevicePostureController) : DevicePostureRepository {
constructor(
    private val postureController: DevicePostureController,
    @Main private val mainDispatcher: CoroutineDispatcher
) : DevicePostureRepository {
    override val currentDevicePosture: Flow<DevicePosture>
        get() = conflatedCallbackFlow {
        get() =
            conflatedCallbackFlow {
                    val sendPostureUpdate = { posture: Int ->
                        val currentDevicePosture = DevicePosture.toPosture(posture)
                        trySendWithFailureLogging(
@@ -51,6 +58,7 @@ constructor(private val postureController: DevicePostureController) : DevicePost

                    awaitClose { postureController.removeCallback(callback) }
                }
                .flowOn(mainDispatcher) // DevicePostureController requirement

    companion object {
        const val TAG = "PostureRepositoryImpl"
+4 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager
import android.hardware.biometrics.BiometricSourceType
import android.provider.Settings
import androidx.annotation.VisibleForTesting
import com.android.app.tracing.ListenersTracing.forEachTraced
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -186,7 +187,9 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
                }
        }

    private fun notifyListeners() = listeners.forEach { it.onBypassStateChanged(bypassEnabled) }
    private fun notifyListeners() = listeners.forEachTraced("KeyguardBypassController") {
        it.onBypassStateChanged(bypassEnabled)
    }

    /**
     * Notify that the biometric unlock has happened.
+8 −1
Original line number Diff line number Diff line
@@ -22,11 +22,14 @@ import android.util.SparseIntArray;

import androidx.annotation.NonNull;

import com.android.app.tracing.ListenersTracing;
import com.android.internal.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.Assert;

import kotlin.Unit;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -75,7 +78,11 @@ public class DevicePostureControllerImpl implements DevicePostureController {
            mCurrentDevicePosture =
                    mDeviceStateToPostureMap.get(state, DEVICE_POSTURE_UNKNOWN);

            mListeners.forEach(l -> l.onPostureChanged(mCurrentDevicePosture));
            ListenersTracing.INSTANCE.forEachTraced(mListeners, "DevicePostureControllerImpl",
                    l -> {
                        l.onPostureChanged(mCurrentDevicePosture);
                        return Unit.INSTANCE;
                    });
        });
    }

Loading