Merge "Fix DMD setting IUdfpsHbmListener before SysUI is ready" into sc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 5e6b904..7947241 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -43,6 +43,7 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
+import android.hardware.fingerprint.IUdfpsHbmListener;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -100,6 +101,8 @@
     @Nullable
     private UdfpsController mUdfpsController;
     @Nullable
+    private IUdfpsHbmListener mUdfpsHbmListener;
+    @Nullable
     private SidefpsController mSidefpsController;
     @VisibleForTesting
     TaskStackListener mTaskStackListener;
@@ -470,6 +473,24 @@
         mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
     }
 
+    /**
+     * Stores the listener received from {@link com.android.server.display.DisplayModeDirector}.
+     *
+     * DisplayModeDirector implements {@link IUdfpsHbmListener} and registers it with this class by
+     * calling {@link CommandQueue#setUdfpsHbmListener(IUdfpsHbmListener)}.
+     */
+    @Override
+    public void setUdfpsHbmListener(IUdfpsHbmListener listener) {
+        mUdfpsHbmListener = listener;
+    }
+
+    /**
+     * @return IUdfpsHbmListener that can be set by DisplayModeDirector.
+     */
+    @Nullable public IUdfpsHbmListener getUdfpsHbmListener() {
+        return mUdfpsHbmListener;
+    }
+
     @Override
     public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
             int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 13b7ebc..fe5ee78 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -512,6 +512,8 @@
                     }
                 }
             }
+        } else if (phase == PHASE_BOOT_COMPLETED) {
+            mDisplayModeDirector.onBootCompleted();
         }
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 997f0e5..07d13c2 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -155,7 +155,6 @@
         mSettingsObserver.observe();
         mDisplayObserver.observe();
         mBrightnessObserver.observe(sensorManager);
-        mUdfpsObserver.observe();
         synchronized (mLock) {
             // We may have a listener already registered before the call to start, so go ahead and
             // notify them to pick up our newly initialized state.
@@ -163,6 +162,16 @@
         }
     }
 
+    /**
+     * Same as {@link #start(SensorManager)}, but for observers that need to be delayed even more,
+     * for example until SystemUI is ready.
+     */
+    public void onBootCompleted() {
+        // UDFPS observer registers a listener with SystemUI which might not be ready until the
+        // system is fully booted.
+        mUdfpsObserver.observe();
+    }
+
     public void setLoggingEnabled(boolean loggingEnabled) {
         if (mLoggingEnabled == loggingEnabled) {
             return;
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index fb2db22..918979c 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -854,7 +854,7 @@
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
         verify(mStatusBarMock, never()).setUdfpsHbmListener(any());
 
-        director.start(createMockSensorManager());
+        director.onBootCompleted();
         verify(mStatusBarMock).setUdfpsHbmListener(eq(director.getUdpfsObserver()));
     }
 
@@ -863,6 +863,7 @@
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[] {60.f, 90.f, 110.f}, 0);
         director.start(createMockSensorManager());
+        director.onBootCompleted();
         ArgumentCaptor<IUdfpsHbmListener> captor =
                 ArgumentCaptor.forClass(IUdfpsHbmListener.class);
         verify(mStatusBarMock).setUdfpsHbmListener(captor.capture());