Merge "Convert KeyguardUpdateMonitor to CoreStartable" into main
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
index 1ee58de..5e76801 100644
--- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
@@ -41,6 +41,7 @@
 import com.android.systemui.util.settings.SecureSettings
 import java.io.PrintWriter
 import javax.inject.Inject
+import dagger.Lazy
 
 /**
  * Handles active unlock settings changes.
@@ -51,6 +52,7 @@
     private val secureSettings: SecureSettings,
     private val contentResolver: ContentResolver,
     private val selectedUserInteractor: SelectedUserInteractor,
+    private val keyguardUpdateMonitor: Lazy<KeyguardUpdateMonitor>,
     dumpManager: DumpManager
 ) : Dumpable {
 
@@ -96,7 +98,6 @@
         UNDER_DISPLAY_FINGERPRINT(3),
     }
 
-    var keyguardUpdateMonitor: KeyguardUpdateMonitor? = null
     private var requestActiveUnlockOnWakeup = false
     private var requestActiveUnlockOnUnlockIntent = false
     private var requestActiveUnlockOnBioFail = false
@@ -316,7 +317,7 @@
             return false
         }
 
-        keyguardUpdateMonitor?.let {
+        keyguardUpdateMonitor.get().let {
             val anyFaceEnrolled = it.isFaceEnabledAndEnrolled
             val anyFingerprintEnrolled = it.isUnlockWithFingerprintPossible(
                     selectedUserInteractor.getSelectedUserId())
@@ -369,13 +370,13 @@
         }")
 
         pw.println("Current state:")
-        keyguardUpdateMonitor?.let {
+        keyguardUpdateMonitor.get().let {
             pw.println("   shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment=" +
                     "${shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment()}")
             pw.println("   isFaceEnabledAndEnrolled=${it.isFaceEnabledAndEnrolled}")
             pw.println("   fpUnlockPossible=${
                 it.isUnlockWithFingerprintPossible(selectedUserInteractor.getSelectedUserId())}")
             pw.println("   udfpsEnrolled=${it.isUdfpsEnrolled}")
-        } ?: pw.println("   keyguardUpdateMonitor is uninitialized")
+        }
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9c61a8a..f3cd01f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -111,6 +111,7 @@
 import com.android.settingslib.Utils;
 import com.android.settingslib.WirelessUtils;
 import com.android.settingslib.fuelgauge.BatteryStatus;
+import com.android.systemui.CoreStartable;
 import com.android.systemui.Dumpable;
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
@@ -175,7 +176,7 @@
  * to be updated.
  */
 @SysUISingleton
-public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpable {
+public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpable, CoreStartable {
 
     private static final String TAG = "KeyguardUpdateMonitor";
     private static final int BIOMETRIC_LOCKOUT_RESET_DELAY_MS = 600;
@@ -347,6 +348,7 @@
     private final LatencyTracker mLatencyTracker;
     private final StatusBarStateController mStatusBarStateController;
     private final Executor mBackgroundExecutor;
+    private final Executor mMainExecutor;
     private final SensorPrivacyManager mSensorPrivacyManager;
     private final ActiveUnlockConfig mActiveUnlockConfig;
     private final IDreamManager mDreamManager;
@@ -354,7 +356,10 @@
     @Nullable
     private final FingerprintManager mFpm;
     @Nullable
+    private final BiometricManager mBiometricManager;
+    @Nullable
     private KeyguardFaceAuthInteractor mFaceAuthInteractor;
+    private final DevicePostureController mDevicePostureController;
     private final TaskStackChangeListeners mTaskStackChangeListeners;
     private final IActivityTaskManager mActivityTaskManager;
     private final SelectedUserInteractor mSelectedUserInteractor;
@@ -370,7 +375,7 @@
     private boolean mIsDreaming;
     private boolean mLogoutEnabled;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-    private FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
+    private final FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
 
     /**
      * Short delay before restarting fingerprint authentication after a successful try. This should
@@ -2105,6 +2110,7 @@
         mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
         mStrongAuthTracker = new StrongAuthTracker(context);
         mBackgroundExecutor = backgroundExecutor;
+        mMainExecutor = mainExecutor;
         mBroadcastDispatcher = broadcastDispatcher;
         mInteractionJankMonitor = interactionJankMonitor;
         mLatencyTracker = latencyTracker;
@@ -2126,7 +2132,7 @@
         mDevicePolicyManager = devicePolicyManager;
         mPackageManager = packageManager;
         mFpm = fingerprintManager;
-        mActiveUnlockConfig.setKeyguardUpdateMonitor(this);
+        mBiometricManager = biometricManager;
         mConfigFaceAuthSupportedPosture = mContext.getResources().getInteger(
                 R.integer.config_face_auth_supported_posture);
         mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;
@@ -2134,10 +2140,14 @@
                 mContext.getResources().getStringArray(
                         R.array.config_fingerprint_listen_on_occluding_activity_packages))
                 .collect(Collectors.toSet());
+        mDevicePostureController = devicePostureController;
         mTaskStackChangeListeners = taskStackChangeListeners;
         mActivityTaskManager = activityTaskManagerService;
         mSelectedUserInteractor = selectedUserInteractor;
 
+        mFingerprintInteractiveToAuthProvider = interactiveToAuthProvider.orElse(null);
+        mIsSystemUser = mUserManager.isSystemUser();
+
         mHandler = new Handler(mainLooper) {
             @Override
             public void handleMessage(Message msg) {
@@ -2252,6 +2262,20 @@
             }
         };
 
+        mTimeFormatChangeObserver = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mHandler.sendMessage(mHandler.obtainMessage(
+                        MSG_TIME_FORMAT_UPDATE,
+                        Settings.System.getString(
+                                mContext.getContentResolver(),
+                                Settings.System.TIME_12_24)));
+            }
+        };
+    }
+
+    @Override
+    public void start() {
         // Since device can't be un-provisioned, we only need to register a content observer
         // to update mDeviceProvisioned when we are...
         if (!mDeviceProvisioned) {
@@ -2297,7 +2321,7 @@
                 mHandler, UserHandle.ALL);
 
         mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
-        mUserTracker.addCallback(mUserChangedCallback, mainExecutor);
+        mUserTracker.addCallback(mUserChangedCallback, mMainExecutor);
 
         mTrustManager.registerTrustListener(this);
 
@@ -2318,8 +2342,8 @@
             mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
         }
 
-        if (biometricManager != null) {
-            biometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
+        if (mBiometricManager != null) {
+            mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
         }
 
         // in case authenticators aren't registered yet at this point:
@@ -2327,7 +2351,7 @@
             @Override
             public void onAllAuthenticatorsRegistered(
                     @BiometricAuthenticator.Modality int modality) {
-                mainExecutor.execute(
+                mMainExecutor.execute(
                         () -> updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE));
             }
 
@@ -2335,7 +2359,7 @@
             public void onEnrollmentsChanged(@BiometricAuthenticator.Modality int modality) {
                 mHandler.obtainMessage(MSG_BIOMETRIC_ENROLLMENT_STATE_CHANGED, modality, 0)
                         .sendToTarget();
-                mainExecutor.execute(
+                mMainExecutor.execute(
                         () -> updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE));
             }
 
@@ -2353,12 +2377,11 @@
             }
         });
         if (mConfigFaceAuthSupportedPosture != DEVICE_POSTURE_UNKNOWN) {
-            devicePostureController.addCallback(mPostureCallback);
+            mDevicePostureController.addCallback(mPostureCallback);
         }
         updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
 
         mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
-        mIsSystemUser = mUserManager.isSystemUser();
         int user = mSelectedUserInteractor.getSelectedUserId(true);
         mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
         mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
@@ -2377,22 +2400,9 @@
         mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
         initializeSimState();
 
-        mTimeFormatChangeObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mHandler.sendMessage(mHandler.obtainMessage(
-                        MSG_TIME_FORMAT_UPDATE,
-                        Settings.System.getString(
-                                mContext.getContentResolver(),
-                                Settings.System.TIME_12_24)));
-            }
-        };
-
         mContext.getContentResolver().registerContentObserver(
                 Settings.System.getUriFor(Settings.System.TIME_12_24),
                 false, mTimeFormatChangeObserver, UserHandle.USER_ALL);
-
-        mFingerprintInteractiveToAuthProvider = interactiveToAuthProvider.orElse(null);
     }
 
     private void initializeSimState() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 3925dd1..13e3835 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -34,6 +34,7 @@
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
 import com.android.keyguard.mediator.ScreenOnCoordinator;
+import com.android.systemui.CoreStartable;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingCollector;
@@ -79,9 +80,12 @@
 import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
 import com.android.wm.shell.keyguard.KeyguardTransitions;
 
+import dagger.Binds;
 import dagger.Lazy;
 import dagger.Module;
 import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
 
 import java.util.concurrent.Executor;
 
@@ -105,7 +109,7 @@
             StartKeyguardTransitionModule.class,
             ResourceTrimmerModule.class,
         })
-public class KeyguardModule {
+public interface KeyguardModule {
     /**
      * Provides our instance of KeyguardViewMediator which is considered optional.
      */
@@ -207,13 +211,19 @@
 
     /** */
     @Provides
-    public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
+    static ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
         return viewMediator.getViewMediatorCallback();
     }
 
     /** */
     @Provides
-    public KeyguardQuickAffordancesMetricsLogger providesKeyguardQuickAffordancesMetricsLogger() {
+    static KeyguardQuickAffordancesMetricsLogger providesKeyguardQuickAffordancesMetricsLogger() {
         return new KeyguardQuickAffordancesMetricsLoggerImpl();
     }
+
+    /** Binds {@link KeyguardUpdateMonitor} as a {@link CoreStartable}. */
+    @Binds
+    @IntoMap
+    @ClassKey(KeyguardUpdateMonitor.class)
+    CoreStartable bindsKeyguardUpdateMonitor(KeyguardUpdateMonitor keyguardUpdateMonitor);
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index 3f76d30..8858d13 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -51,6 +51,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import dagger.Lazy
 
 @SmallTest
 class ActiveUnlockConfigTest : SysuiTestCase() {
@@ -60,6 +61,7 @@
     @Mock private lateinit var dumpManager: DumpManager
     @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var lazyKeyguardUpdateMonitor: Lazy<KeyguardUpdateMonitor>
     @Mock private lateinit var mockPrintWriter: PrintWriter
 
     @Captor private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
@@ -72,6 +74,7 @@
         MockitoAnnotations.initMocks(this)
 
         whenever(selectedUserInteractor.getSelectedUserId()).thenReturn(currentUser)
+        whenever(lazyKeyguardUpdateMonitor.get()).thenReturn(keyguardUpdateMonitor)
         secureSettings = FakeSettings()
         activeUnlockConfig =
             ActiveUnlockConfig(
@@ -79,6 +82,7 @@
                 secureSettings,
                 contentResolver,
                 selectedUserInteractor,
+                lazyKeyguardUpdateMonitor,
                 dumpManager
             )
     }
@@ -260,7 +264,6 @@
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
 
         // GIVEN fingerprint and face are NOT enrolled
-        activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor
         `when`(keyguardUpdateMonitor.isFaceEnabledAndEnrolled).thenReturn(false)
         `when`(keyguardUpdateMonitor.isUnlockWithFingerprintPossible(0)).thenReturn(false)
 
@@ -290,7 +293,6 @@
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL))
 
         // GIVEN fingerprint and face are both enrolled
-        activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor
         `when`(keyguardUpdateMonitor.isFaceEnabledAndEnrolled).thenReturn(true)
         `when`(keyguardUpdateMonitor.isUnlockWithFingerprintPossible(0)).thenReturn(true)
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 1ab634c..d03a898 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -2283,6 +2283,7 @@
                     Optional.of(mInteractiveToAuthProvider),
                     mTaskStackChangeListeners, mSelectedUserInteractor, mActivityTaskManager);
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
+            start();
         }
 
         public boolean hasSimStateJustChanged() {