From e1bde69d4fba6989cdc4579885cf62c38af7206d Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 3 Mar 2023 12:50:50 -0800 Subject: [PATCH] Do not pass in anon callback. The anon callback gets deferenced after the first few calls. Make sure that it is a class field. Also update the documentation to reflect this. There are no known bugs due to this, but proactively fixing this to avoid unintended behavior. Bug: 267821080 Test: add logs to see if the callbacks are called continuously. onBiometricRunningStateChanged is called pretty much every time we go to LS and leave LS. Change-Id: If7fb2450f9025b85a30a10612966561c020ec865 --- .../keyguard/KeyguardUpdateMonitor.java | 4 ++- .../interactor/PrimaryBouncerInteractor.kt | 31 ++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 739cd3fb63aed..90230019ca5ce 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -3620,7 +3620,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab * Register to receive notifications about general keyguard information * (see {@link KeyguardUpdateMonitorCallback}. * - * @param callback The callback to register + * @param callback The callback to register. Stay away from passing anonymous instances + * as they will likely be dereferenced. Ensure that the callback is a class + * field to persist it. */ public void registerCallback(KeyguardUpdateMonitorCallback callback) { Assert.isMainThread(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt index c709fd18298c4..6d8a849b1f313 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt @@ -122,21 +122,24 @@ constructor( val isInteractable: Flow = bouncerExpansion.map { it > 0.9 } val sideFpsShowing: Flow = repository.sideFpsShowing - init { - keyguardUpdateMonitor.registerCallback( - object : KeyguardUpdateMonitorCallback() { - override fun onBiometricRunningStateChanged( - running: Boolean, - biometricSourceType: BiometricSourceType? - ) { - updateSideFpsVisibility() - } + /** + * This callback needs to be a class field so it does not get garbage collected. + */ + val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() { + override fun onBiometricRunningStateChanged( + running: Boolean, + biometricSourceType: BiometricSourceType? + ) { + updateSideFpsVisibility() + } - override fun onStrongAuthStateChanged(userId: Int) { - updateSideFpsVisibility() - } - } - ) + override fun onStrongAuthStateChanged(userId: Int) { + updateSideFpsVisibility() + } + } + + init { + keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) } // TODO(b/243685699): Move isScrimmed logic to data layer.