diff options
23 files changed, 318 insertions, 42 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt index 1c994731c393..126471234fa1 100644 --- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt @@ -32,6 +32,9 @@ import com.android.systemui.authentication.shared.model.AuthenticationWipeModel. import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable +import com.android.systemui.scene.domain.SceneFrameworkTableLog import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -66,6 +69,7 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, private val repository: AuthenticationRepository, private val selectedUserInteractor: SelectedUserInteractor, + @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer, ) { /** * The currently-configured authentication method. This determines how the authentication @@ -85,7 +89,11 @@ constructor( * `true` even when the lockscreen is showing and still needs to be dismissed by the user to * proceed. */ - val authenticationMethod: Flow<AuthenticationMethodModel> = repository.authenticationMethod + val authenticationMethod: Flow<AuthenticationMethodModel> = + repository.authenticationMethod.logDiffsForTable( + tableLogBuffer = tableLogBuffer, + initialValue = AuthenticationMethodModel.None, + ) /** * Whether the auto confirm feature is enabled for the currently-selected user. diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt index 4e45fcc25fb8..744fd7e94ab4 100644 --- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt +++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt @@ -16,6 +16,9 @@ package com.android.systemui.authentication.shared.model +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger + /** Enumerates all known authentication methods. */ sealed class AuthenticationMethodModel( /** @@ -24,8 +27,8 @@ sealed class AuthenticationMethodModel( * "Secure" authentication methods require authentication to unlock the device. Non-secure auth * methods simply require user dismissal. */ - open val isSecure: Boolean, -) { + open val isSecure: Boolean +) : Diffable<AuthenticationMethodModel> { /** * Device doesn't use a secure authentication method. Either there is no lockscreen or the lock * screen can be swiped away when displayed. @@ -39,4 +42,8 @@ sealed class AuthenticationMethodModel( data object Pattern : AuthenticationMethodModel(isSecure = true) data object Sim : AuthenticationMethodModel(isSecure = true) + + override fun logDiffs(prevVal: AuthenticationMethodModel, row: TableRowLogger) { + row.logChange(columnName = "authenticationMethod", value = toString()) + } } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt index cdd2b054711e..079d624e6fe0 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractor.kt @@ -19,6 +19,7 @@ package com.android.systemui.deviceentry.domain.interactor import com.android.systemui.CoreStartable import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus +import com.android.systemui.log.table.TableLogBuffer import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow @@ -81,6 +82,8 @@ interface DeviceEntryFaceAuthInteractor : CoreStartable { /** Whether face auth is considered class 3 */ fun isFaceAuthStrong(): Boolean + + suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) } /** @@ -93,17 +96,17 @@ interface DeviceEntryFaceAuthInteractor : CoreStartable { */ interface FaceAuthenticationListener { /** Receive face isAuthenticated updates */ - fun onAuthenticatedChanged(isAuthenticated: Boolean) + fun onAuthenticatedChanged(isAuthenticated: Boolean) = Unit /** Receive face authentication status updates */ - fun onAuthenticationStatusChanged(status: FaceAuthenticationStatus) + fun onAuthenticationStatusChanged(status: FaceAuthenticationStatus) = Unit /** Receive status updates whenever face detection runs */ - fun onDetectionStatusChanged(status: FaceDetectionStatus) + fun onDetectionStatusChanged(status: FaceDetectionStatus) = Unit - fun onLockoutStateChanged(isLockedOut: Boolean) + fun onLockoutStateChanged(isLockedOut: Boolean) = Unit - fun onRunningStateChanged(isRunning: Boolean) + fun onRunningStateChanged(isRunning: Boolean) = Unit - fun onAuthEnrollmentStateChanged(enrolled: Boolean) + fun onAuthEnrollmentStateChanged(enrolled: Boolean) = Unit } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt index 4ddc98cd434f..5b6859761705 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt @@ -25,7 +25,10 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository import com.android.systemui.keyguard.DismissCallbackRegistry +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.scene.data.model.asIterable +import com.android.systemui.scene.domain.SceneFrameworkTableLog import com.android.systemui.scene.domain.interactor.SceneBackInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.Scenes @@ -33,9 +36,11 @@ import com.android.systemui.util.kotlin.pairwise import com.android.systemui.utils.coroutines.flow.mapLatestConflated import javax.inject.Inject import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter @@ -43,6 +48,7 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch /** * Hosts application business logic related to device entry. @@ -62,6 +68,7 @@ constructor( private val alternateBouncerInteractor: AlternateBouncerInteractor, private val dismissCallbackRegistry: DismissCallbackRegistry, sceneBackInteractor: SceneBackInteractor, + @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer, ) { /** * Whether the device is unlocked. @@ -147,6 +154,11 @@ constructor( ) { enteredDirectly, enteredOnBackStack -> enteredOnBackStack || enteredDirectly } + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "isDeviceEntered", + initialValue = false, + ) .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, @@ -184,6 +196,11 @@ constructor( deviceUnlockStatus.deviceUnlockSource?.dismissesLockscreen == false)) && !isDeviceEntered } + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "canSwipeToEnter", + initialValue = false, + ) .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, @@ -271,4 +288,29 @@ constructor( fun lockNow() { deviceUnlockedInteractor.lockNow() } + + suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) { + coroutineScope { + launch { + isDeviceEntered + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "isDeviceEntered", + initialValue = isDeviceEntered.value, + ) + .collect() + } + + launch { + canSwipeToEnter + .map { it?.toString() ?: "" } + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "canSwipeToEnter", + initialValue = canSwipeToEnter.value?.toString() ?: "", + ) + .collect() + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt index 68aef521be7b..b1be9a209a0a 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt @@ -33,8 +33,11 @@ import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.TrustInteractor import com.android.systemui.lifecycle.ExclusiveActivatable +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.power.shared.model.WakeSleepReason +import com.android.systemui.scene.domain.SceneFrameworkTableLog import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.util.settings.repository.UserAwareSecureSettingsRepository import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated @@ -48,6 +51,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -74,6 +78,7 @@ constructor( private val systemPropertiesHelper: SystemPropertiesHelper, private val userAwareSecureSettingsRepository: UserAwareSecureSettingsRepository, private val keyguardInteractor: KeyguardInteractor, + @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer, ) : ExclusiveActivatable() { private val deviceUnlockSource = @@ -179,17 +184,33 @@ constructor( private val lockNowRequests = Channel<Unit>() override suspend fun onActivated(): Nothing { - authenticationInteractor.authenticationMethod.collectLatest { authMethod -> - if (!authMethod.isSecure) { - // Device remains unlocked as long as the authentication method is not secure. - Log.d(TAG, "remaining unlocked because auth method not secure") - repository.deviceUnlockStatus.value = DeviceUnlockStatus(true, null) - } else if (authMethod == AuthenticationMethodModel.Sim) { - // Device remains locked while SIM is locked. - Log.d(TAG, "remaining locked because SIM locked") - repository.deviceUnlockStatus.value = DeviceUnlockStatus(false, null) - } else { - handleLockAndUnlockEvents() + coroutineScope { + launch { + authenticationInteractor.authenticationMethod.collectLatest { authMethod -> + if (!authMethod.isSecure) { + // Device remains unlocked as long as the authentication method is not + // secure. + Log.d(TAG, "remaining unlocked because auth method not secure") + repository.deviceUnlockStatus.value = DeviceUnlockStatus(true, null) + } else if (authMethod == AuthenticationMethodModel.Sim) { + // Device remains locked while SIM is locked. + Log.d(TAG, "remaining locked because SIM locked") + repository.deviceUnlockStatus.value = DeviceUnlockStatus(false, null) + } else { + handleLockAndUnlockEvents() + } + } + } + + launch { + deviceUnlockStatus + .map { it.isUnlocked } + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "isUnlocked", + initialValue = deviceUnlockStatus.value.isUnlocked, + ) + .collect() } } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt index 9b8c2b1acc33..ecc4dbc2326a 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/NoopDeviceEntryFaceAuthInteractor.kt @@ -19,6 +19,7 @@ package com.android.systemui.deviceentry.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.shared.model.FaceAuthenticationStatus import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus +import com.android.systemui.log.table.TableLogBuffer import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -73,4 +74,6 @@ class NoopDeviceEntryFaceAuthInteractor @Inject constructor() : DeviceEntryFaceA override fun onWalletLaunched() = Unit override fun onDeviceUnfolded() {} + + override suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) {} } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt index b19b2d9ece02..4b90e1d52ea0 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt @@ -44,6 +44,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.log.FaceAuthenticationLogger +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.SceneInteractor @@ -53,13 +55,16 @@ import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.sample +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import dagger.Lazy 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.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull @@ -379,6 +384,27 @@ constructor( .launchIn(applicationScope) } + override suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) { + conflatedCallbackFlow { + val listener = + object : FaceAuthenticationListener { + override fun onAuthEnrollmentStateChanged(enrolled: Boolean) { + trySend(isFaceAuthEnabledAndEnrolled()) + } + } + + registerListener(listener) + + awaitClose { unregisterListener(listener) } + } + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "isFaceAuthEnabledAndEnrolled", + initialValue = isFaceAuthEnabledAndEnrolled(), + ) + .collect() + } + companion object { const val TAG = "DeviceEntryFaceAuthInteractor" } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt index 42cbd7d39248..a1f288edcdd3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt @@ -24,6 +24,8 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.kotlin.sample @@ -32,6 +34,7 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach @@ -166,4 +169,14 @@ constructor( isKeyguardEnabled.value && lockPatternUtils.isLockScreenDisabled(userId) } } + + suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) { + isKeyguardEnabled + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "isKeyguardEnabled", + initialValue = isKeyguardEnabled.value, + ) + .collect() + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index 75178f0ffef0..3739d17da6c4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -42,6 +42,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED import com.android.systemui.keyguard.shared.model.StatusBarState +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag @@ -60,6 +62,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combineTransform import kotlinx.coroutines.flow.debounce @@ -533,6 +536,16 @@ constructor( repository.setNotificationStackAbsoluteBottom(bottom) } + suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) { + isDozing + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + columnName = "isDozing", + initialValue = isDozing.value, + ) + .collect() + } + companion object { private const val TAG = "KeyguardInteractor" /** diff --git a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt index f15a7b30dce7..f8d442de0f55 100644 --- a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt @@ -22,6 +22,8 @@ import com.android.systemui.camera.CameraGestureHelper import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorActual import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.power.data.repository.PowerRepository import com.android.systemui.power.shared.model.DozeScreenStateModel @@ -35,6 +37,7 @@ import javax.inject.Provider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -228,6 +231,15 @@ constructor( repository.updateWakefulness(powerButtonLaunchGestureTriggered = true) } + suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) { + detailedWakefulness + .logDiffsForTable( + tableLogBuffer = tableLogBuffer, + initialValue = detailedWakefulness.value, + ) + .collect() + } + companion object { private const val FSI_WAKE_WHY = "full_screen_intent" diff --git a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakefulnessModel.kt b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakefulnessModel.kt index 0f49c94c3195..297c6af5a4a7 100644 --- a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakefulnessModel.kt +++ b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakefulnessModel.kt @@ -1,6 +1,8 @@ package com.android.systemui.power.shared.model import com.android.systemui.keyguard.KeyguardService +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger /** * Models whether the device is awake or asleep, along with information about why we're in that @@ -35,7 +37,7 @@ data class WakefulnessModel( * to a subsequent power gesture. */ val powerButtonLaunchGestureTriggered: Boolean = false, -) { +) : Diffable<WakefulnessModel> { fun isAwake() = internalWakefulnessState == WakefulnessState.AWAKE || internalWakefulnessState == WakefulnessState.STARTING_TO_WAKE @@ -58,4 +60,8 @@ data class WakefulnessModel( return isAwake() && (lastWakeReason == WakeSleepReason.TAP || lastWakeReason == WakeSleepReason.GESTURE) } + + override fun logDiffs(prevVal: WakefulnessModel, row: TableRowLogger) { + row.logChange(columnName = "wakefulness", value = toString()) + } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt index be792df340c9..f2f237ac987e 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt @@ -16,13 +16,27 @@ package com.android.systemui.scene.domain +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.scene.domain.resolver.SceneResolverModule import dagger.Module +import dagger.Provides +import javax.inject.Qualifier -@Module( - includes = - [ - SceneResolverModule::class, - ] -) -object SceneDomainModule +@Module(includes = [SceneResolverModule::class]) +object SceneDomainModule { + + @JvmStatic + @Provides + @SysUISingleton + @SceneFrameworkTableLog + fun provideSceneFrameworkTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer { + return factory.create("SceneFrameworkTableLog", 100) + } +} + +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +annotation class SceneFrameworkTableLog diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneBackInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneBackInteractor.kt index bebd398ac972..c9d8e0244d20 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneBackInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneBackInteractor.kt @@ -18,11 +18,16 @@ package com.android.systemui.scene.domain.interactor import com.android.compose.animation.scene.SceneKey import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.TableRowLogger import com.android.systemui.scene.data.model.SceneStack +import com.android.systemui.scene.data.model.asIterable import com.android.systemui.scene.data.model.peek import com.android.systemui.scene.data.model.pop import com.android.systemui.scene.data.model.push import com.android.systemui.scene.data.model.sceneStackOf +import com.android.systemui.scene.domain.SceneFrameworkTableLog import com.android.systemui.scene.shared.logger.SceneLogger import com.android.systemui.scene.shared.model.SceneContainerConfig import javax.inject.Inject @@ -39,6 +44,7 @@ class SceneBackInteractor constructor( private val logger: SceneLogger, private val sceneContainerConfig: SceneContainerConfig, + @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer, ) { private val _backStack = MutableStateFlow(sceneStackOf()) val backStack: StateFlow<SceneStack> = _backStack.asStateFlow() @@ -58,6 +64,7 @@ constructor( fun onSceneChange(from: SceneKey, to: SceneKey) { check(from != to) { "from == to, from=${from.debugName}, to=${to.debugName}" } + val prevVal = backStack.value _backStack.update { stack -> when (stackOperation(from, to, stack)) { null -> stack @@ -68,12 +75,21 @@ constructor( } } logger.logSceneBackStack(backStack.value) + tableLogBuffer.logDiffs( + prevVal = DiffableSceneStack(prevVal), + newVal = DiffableSceneStack(backStack.value), + ) } /** Applies the given [transform] to the back stack. */ fun updateBackStack(transform: (SceneStack) -> SceneStack) { + val prevVal = backStack.value _backStack.update { stack -> transform(stack) } logger.logSceneBackStack(backStack.value) + tableLogBuffer.logDiffs( + prevVal = DiffableSceneStack(prevVal), + newVal = DiffableSceneStack(backStack.value), + ) } private fun stackOperation(from: SceneKey, to: SceneKey, stack: SceneStack): StackOperation? { @@ -106,4 +122,15 @@ constructor( private data object Push : StackOperation private data object Pop : StackOperation + + private class DiffableSceneStack(private val sceneStack: SceneStack) : + Diffable<DiffableSceneStack> { + + override fun logDiffs(prevVal: DiffableSceneStack, row: TableRowLogger) { + row.logChange( + columnName = "backStack", + value = sceneStack.asIterable().joinToString { it.debugName }, + ) + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt index 8bc9d96c064a..9c04323f2a0e 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt @@ -27,14 +27,19 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.TableRowLogger import com.android.systemui.scene.data.repository.SceneContainerRepository import com.android.systemui.scene.domain.resolver.SceneResolver import com.android.systemui.scene.shared.logger.SceneLogger import com.android.systemui.scene.shared.model.SceneFamilies import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.util.kotlin.pairwise import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -47,6 +52,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch /** * Generic business logic and app state accessors for the scene framework. @@ -562,6 +568,28 @@ constructor( decrementActiveTransitionAnimationCount() } + suspend fun hydrateTableLogBuffer(tableLogBuffer: TableLogBuffer) { + coroutineScope { + launch { + currentScene + .map { sceneKey -> DiffableSceneKey(key = sceneKey) } + .pairwise() + .collect { (prev, current) -> + tableLogBuffer.logDiffs(prevVal = prev, newVal = current) + } + } + + launch { + currentOverlays + .map { overlayKeys -> DiffableOverlayKeys(keys = overlayKeys) } + .pairwise() + .collect { (prev, current) -> + tableLogBuffer.logDiffs(prevVal = prev, newVal = current) + } + } + } + } + private fun decrementActiveTransitionAnimationCount() { repository.activeTransitionAnimationCount.update { current -> (current - 1).also { @@ -573,4 +601,20 @@ constructor( } } } + + private class DiffableSceneKey(private val key: SceneKey) : Diffable<DiffableSceneKey> { + override fun logDiffs(prevVal: DiffableSceneKey, row: TableRowLogger) { + row.logChange(columnName = "currentScene", value = key.debugName) + } + } + + private class DiffableOverlayKeys(private val keys: Set<OverlayKey>) : + Diffable<DiffableOverlayKeys> { + override fun logDiffs(prevVal: DiffableOverlayKeys, row: TableRowLogger) { + row.logChange( + columnName = "currentOverlays", + value = keys.joinToString { key -> key.debugName }, + ) + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 8602884ec4ee..2fd584176220 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -45,6 +45,7 @@ import com.android.systemui.keyguard.DismissCallbackRegistry import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.keyguardScenes +import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.model.SceneContainerPlugin import com.android.systemui.model.SysUiState import com.android.systemui.model.updateFlags @@ -54,6 +55,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.scene.data.model.asIterable import com.android.systemui.scene.data.model.sceneStackOf +import com.android.systemui.scene.domain.SceneFrameworkTableLog import com.android.systemui.scene.domain.interactor.DisabledContentInteractor import com.android.systemui.scene.domain.interactor.SceneBackInteractor import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor @@ -145,6 +147,7 @@ constructor( private val disabledContentInteractor: DisabledContentInteractor, private val activityTransitionAnimator: ActivityTransitionAnimator, private val shadeModeInteractor: ShadeModeInteractor, + @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer, ) : CoreStartable { private val centralSurfaces: CentralSurfaces? get() = centralSurfacesOptLazy.get().getOrNull() @@ -154,6 +157,7 @@ constructor( override fun start() { if (SceneContainerFlag.isEnabled) { sceneLogger.logFrameworkEnabled(isEnabled = true) + applicationScope.launch { hydrateTableLogBuffer() } hydrateVisibility() automaticallySwitchScenes() hydrateSystemUiState() @@ -224,6 +228,16 @@ constructor( } } + private suspend fun hydrateTableLogBuffer() { + coroutineScope { + launch { sceneInteractor.hydrateTableLogBuffer(tableLogBuffer) } + launch { keyguardEnabledInteractor.hydrateTableLogBuffer(tableLogBuffer) } + launch { faceUnlockInteractor.hydrateTableLogBuffer(tableLogBuffer) } + launch { powerInteractor.hydrateTableLogBuffer(tableLogBuffer) } + launch { keyguardInteractor.hydrateTableLogBuffer(tableLogBuffer) } + } + } + private fun resetShadeSessions() { applicationScope.launch { combine( diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt index 59d812403777..01451502b859 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractor.kt @@ -19,6 +19,9 @@ package com.android.systemui.shade.domain.interactor import android.provider.Settings import androidx.annotation.FloatRange import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.log.table.TableLogBuffer +import com.android.systemui.log.table.logDiffsForTable +import com.android.systemui.scene.domain.SceneFrameworkTableLog import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.shade.shared.model.ShadeMode @@ -81,8 +84,9 @@ class ShadeModeInteractorImpl @Inject constructor( @Application applicationScope: CoroutineScope, - repository: ShadeRepository, + private val repository: ShadeRepository, secureSettingsRepository: SecureSettingsRepository, + @SceneFrameworkTableLog private val tableLogBuffer: TableLogBuffer, ) : ShadeModeInteractor { private val isDualShadeEnabled: Flow<Boolean> = @@ -93,17 +97,17 @@ constructor( override val isShadeLayoutWide: StateFlow<Boolean> = repository.isShadeLayoutWide + private val shadeModeInitialValue: ShadeMode + get() = + determineShadeMode( + isDualShadeEnabled = DUAL_SHADE_ENABLED_DEFAULT, + isShadeLayoutWide = repository.isShadeLayoutWide.value, + ) + override val shadeMode: StateFlow<ShadeMode> = combine(isDualShadeEnabled, repository.isShadeLayoutWide, ::determineShadeMode) - .stateIn( - applicationScope, - SharingStarted.Eagerly, - initialValue = - determineShadeMode( - isDualShadeEnabled = DUAL_SHADE_ENABLED_DEFAULT, - isShadeLayoutWide = repository.isShadeLayoutWide.value, - ), - ) + .logDiffsForTable(tableLogBuffer = tableLogBuffer, initialValue = shadeModeInitialValue) + .stateIn(applicationScope, SharingStarted.Eagerly, initialValue = shadeModeInitialValue) @FloatRange(from = 0.0, to = 1.0) override fun getTopEdgeSplitFraction(): Float = 0.5f diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt index a8199a402ef1..8b3ce0f69742 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeMode.kt @@ -16,15 +16,18 @@ package com.android.systemui.shade.shared.model +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger + /** Enumerates all known modes of operation of the shade. */ -sealed interface ShadeMode { +sealed class ShadeMode : Diffable<ShadeMode> { /** * The single or "accordion" shade where the QS and notification parts are in two vertically * stacked panels and the user can swipe up and down to expand or collapse between the two * parts. */ - data object Single : ShadeMode + data object Single : ShadeMode() /** * The split shade where, on large screens and unfolded foldables, the QS and notification parts @@ -32,14 +35,18 @@ sealed interface ShadeMode { * * Note: This isn't the only mode where the shade is wide. */ - data object Split : ShadeMode + data object Split : ShadeMode() /** * The dual shade where the QS and notification parts each have their own independently * expandable/collapsible panel on either side of the large screen / unfolded device or sharing * a space on a small screen or folded device. */ - data object Dual : ShadeMode + data object Dual : ShadeMode() + + override fun logDiffs(prevVal: ShadeMode, row: TableRowLogger) { + row.logChange("shadeMode", toString()) + } companion object { @JvmStatic fun dual(): Dual = Dual diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorKosmos.kt index 2bd104dd375d..48b801cb06be 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorKosmos.kt @@ -20,6 +20,7 @@ import com.android.systemui.authentication.data.repository.authenticationReposit import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.user.domain.interactor.selectedUserInteractor val Kosmos.authenticationInteractor by @@ -29,5 +30,6 @@ val Kosmos.authenticationInteractor by backgroundDispatcher = testDispatcher, repository = authenticationRepository, selectedUserInteractor = selectedUserInteractor, + tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"), ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt index 1d3fd300da06..c927b5563bba 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt @@ -22,6 +22,7 @@ import com.android.systemui.deviceentry.data.repository.deviceEntryRepository import com.android.systemui.keyguard.dismissCallbackRegistry import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.scene.domain.interactor.sceneBackInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor @@ -36,5 +37,6 @@ val Kosmos.deviceEntryInteractor by alternateBouncerInteractor = alternateBouncerInteractor, dismissCallbackRegistry = dismissCallbackRegistry, sceneBackInteractor = sceneBackInteractor, + tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"), ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt index e4c7df64fdc6..9e36428d119d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt @@ -25,6 +25,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testScope import com.android.systemui.lifecycle.activateIn +import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.util.settings.data.repository.userAwareSecureSettingsRepository @@ -40,6 +41,7 @@ val Kosmos.deviceUnlockedInteractor by Fixture { systemPropertiesHelper = fakeSystemPropertiesHelper, userAwareSecureSettingsRepository = userAwareSecureSettingsRepository, keyguardInteractor = keyguardInteractor, + tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"), ) .apply { activateIn(testScope) } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorKosmos.kt index e46ede65bfb6..e9ba42547883 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorKosmos.kt @@ -18,6 +18,7 @@ package com.android.systemui.scene.domain.interactor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture +import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.scene.sceneContainerConfig import com.android.systemui.scene.shared.logger.sceneLogger @@ -25,5 +26,6 @@ val Kosmos.sceneBackInteractor by Fixture { SceneBackInteractor( logger = sceneLogger, sceneContainerConfig = sceneContainerConfig, + tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"), ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt index d105326ec3d0..65bfafbfa9b0 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testScope +import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.model.sysUiState import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.scene.domain.interactor.disabledContentInteractor @@ -89,5 +90,6 @@ val Kosmos.sceneContainerStartable by Fixture { disabledContentInteractor = disabledContentInteractor, activityTransitionAnimator = activityTransitionAnimator, shadeModeInteractor = shadeModeInteractor, + tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"), ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt index a4631f17cb37..2ba9c8094aac 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeModeInteractorKosmos.kt @@ -21,6 +21,7 @@ import android.provider.Settings import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.res.R import com.android.systemui.shade.data.repository.fakeShadeRepository import com.android.systemui.shade.data.repository.shadeRepository @@ -31,6 +32,7 @@ val Kosmos.shadeModeInteractor by Fixture { applicationScope = applicationCoroutineScope, repository = shadeRepository, secureSettingsRepository = fakeSecureSettingsRepository, + tableLogBuffer = logcatTableLogBuffer(this, "sceneFrameworkTableLogBuffer"), ) } |