Disable "Night Light" mode while in VR mode.

- Also, re-enable when leaving VR mode (if necessary).

Bug: 31161777

Change-Id: Ia40823a6105c649c1cf1be9b6410b12816a50d0c
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index e7fd3d8..0ec48b9 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -33,8 +33,11 @@
 import android.opengl.Matrix;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings.Secure;
+import android.service.vr.IVrManager;
+import android.service.vr.IVrStateCallbacks;
 import android.util.MathUtils;
 import android.util.Slog;
 import android.view.animation.AnimationUtils;
@@ -44,7 +47,9 @@
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
+import com.android.server.vr.VrManagerService;
 
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.Calendar;
 import java.util.TimeZone;
 
@@ -83,6 +88,31 @@
     private static final ColorMatrixEvaluator COLOR_MATRIX_EVALUATOR = new ColorMatrixEvaluator();
 
     private final Handler mHandler;
+    private final AtomicBoolean mIgnoreAllColorMatrixChanges = new AtomicBoolean();
+    private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
+        @Override
+        public void onVrStateChanged(final boolean enabled) {
+            // Turn off all night mode display stuff while device is in VR mode.
+            mIgnoreAllColorMatrixChanges.set(enabled);
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    // Cancel in-progress animations
+                    if (mColorMatrixAnimator != null) {
+                        mColorMatrixAnimator.cancel();
+                    }
+
+                    final DisplayTransformManager dtm =
+                            getLocalService(DisplayTransformManager.class);
+                    if (enabled) {
+                        dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, MATRIX_IDENTITY);
+                    } else if (mController.isActivated()) {
+                        dtm.setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, MATRIX_NIGHT);
+                    }
+                }
+            });
+        }
+    };
 
     private int mCurrentUser = UserHandle.USER_NULL;
     private ContentObserver mUserSetupObserver;
@@ -105,7 +135,17 @@
 
     @Override
     public void onBootPhase(int phase) {
-        if (phase == PHASE_BOOT_COMPLETED) {
+        if (phase == PHASE_SYSTEM_SERVICES_READY) {
+            IVrManager vrManager =
+                    (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
+            if (vrManager != null) {
+                try {
+                    vrManager.registerListener(mVrStateCallbacks);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Failed to register VR mode state listener: " + e);
+                }
+            }
+        } else if (phase == PHASE_BOOT_COMPLETED) {
             mBootCompleted = true;
 
             // Register listeners now that boot is complete.
@@ -234,6 +274,11 @@
                 mColorMatrixAnimator.cancel();
             }
 
+            // Don't do any color matrix change animations if we are ignoring them anyway.
+            if (mIgnoreAllColorMatrixChanges.get()) {
+                return;
+            }
+
             final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
             final float[] from = dtm.getColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY);
             final float[] to = mIsActivated ? MATRIX_NIGHT : null;